diff --git a/mozilla/webtools/addons/shared/lib/addon.class.php b/mozilla/webtools/addons/shared/lib/addon.class.php new file mode 100644 index 00000000000..86c733d6c54 --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/addon.class.php @@ -0,0 +1,299 @@ +db =& $db; + $this->tpl =& $tpl; + + // If $ID is set, attempt to retrieve data. + if (!empty($ID)) { + $this->ID = $ID; + $this->getAddOn(); + } + } + + /** + * Get all commonly used AddOn information. + */ + function getAddOn() { + $this->getAddonCats(); + $this->getComments(); + $this->getCurrentVersion(); + $this->getMainPreview(); + $this->getUserInfo(); + } + + /** + * Get the "highlight" for the current AddOn. + */ + function getMainPreview() { + // Gather previews information. + $this->db->query(" + SELECT + PreviewID, + PreviewURI, + Caption + FROM + previews + WHERE + ID = '{$this->ID}' AND + preview = 'YES' + LIMIT 1 + ", SQL_INIT, SQL_ASSOC); + + if (!empty($this->db->record)) { + $this->setVars($this->db->record); + + if (file_exists(ROOT_PATH.$this->PreviewURI)) { + $size = getimagesize(ROOT_PATH.$this->PreviewURI); + $this->setVar('PreviewWidth',$size[0]); + $this->setVar('PreviewHeight',$size[1]); + } + } + + } + + /** + * Get all preview information attached to the current AddOn. + */ + function getPreviews() { + // Gather preview information + $this->db->query(" + SELECT + PreviewURI, + caption + FROM + previews + WHERE + ID = {$this->ID} + ORDER BY + PreviewID ASC + ", SQL_NONE); + + while ($this->db->next(SQL_ASSOC)) { + $result = $this->db->record; + $uri = $result['PreviewURI']; + list($src_width, $src_height, $type, $attr) = getimagesize(ROOT_PATH.$uri); + $this->Previews[] = array( + 'PreviewURI' => $uri, + 'caption' => $result['caption'], + 'width' => $src_width, + 'height' => $src_height + ); + } + } + + /** + * Get all previous versions of the current AddOn. + */ + function getHistory() { + $this->db->query(" + SELECT + TV.vID, + TV.Version, + TV.MinAppVer, + TV.MaxAppVer, + TV.Size, + TV.URI, + TV.Notes, + UNIX_TIMESTAMP(TV.DateAdded) AS VerDateAdded, + TA.AppName, + TOS.OSName + FROM + version TV + INNER JOIN applications TA ON TV.AppID = TA.AppID + INNER JOIN os TOS ON TV.OSID = TOS.OSID + WHERE + TV.ID = {$this->ID} AND + approved = 'YES' + ORDER BY + VerDateAdded DESC + ", SQL_ALL, SQL_ASSOC); + + $this->History = $this->db->record; + } + + /** + * Get information about the most recent verison of the current AddOn. + */ + function getCurrentVersion() { + $this->db->query(" + SELECT + version.vID, + version.Version, + version.MinAppVer, + version.MaxAppVer, + version.Size, + version.URI, + version.Notes, + version.DateAdded as VersionDateAdded, + applications.AppName, + os.OSName + FROM + version + INNER JOIN applications ON version.AppID = applications.AppID + INNER JOIN os ON version.OSID = os.OSID + WHERE + version.ID = '{$this->ID}' AND + version.approved = 'YES' + ORDER BY + version.DateAdded DESC + LIMIT 1 + ", SQL_INIT, SQL_ASSOC); + + if (!empty($this->db->record)) { + $this->setVars($this->db->record); + } + } + + /** + * Retrieve user information. + * + * @todo have this function set a User object instead + */ + function getUserInfo() { + // Gather addons metadata, user info. + $this->db->query(" + SELECT + main.*, + userprofiles.UserID, + userprofiles.UserName, + userprofiles.UserEmail, + userprofiles.UserWebsite, + userprofiles.UserEmailHide + FROM + main + INNER JOIN authorxref ON authorxref.ID = main.ID + INNER JOIN userprofiles ON userprofiles.UserID = authorxref.UserID + WHERE + main.ID = '{$this->ID}' + ", SQL_INIT, SQL_ASSOC); + + if (!empty($this->db->record)) { + $this->setVars($this->db->record); + } + } + + /** + * Get comments attached to this Addon. + * + * @param int $limit number of rows to limit by. + * @todo add left/right limit clauses i.e. LIMIT 10,20 to work with pagination + */ + function getComments($limit=5) { + // Gather 10 latest comments. + $this->db->query(" + SELECT + CommentID, + CommentName, + CommentTitle, + CommentNote, + CommentDate, + CommentVote, + `helpful-yes` as helpful_yes, + `helpful-no` as helpful_no, + `helpful-yes` + `helpful-no` as helpful_total + FROM + feedback + WHERE + ID = '{$this->ID}' AND + CommentNote IS NOT NULL + ORDER BY + CommentDate DESC + LIMIT {$limit} + ", SQL_ALL, SQL_ASSOC); + + $this->setVar('Comments',$this->db->record); + } + + /** + * Retrieve all categories attached to the current AddOn. + */ + function getAddonCats() { + // Gather addon categories. + $this->db->query(" + SELECT DISTINCT + categories.CatName, + categories.CategoryID + FROM + categoryxref + INNER JOIN categories ON categoryxref.CategoryID = categories.CategoryID + INNER JOIN main ON categoryxref.ID = main.ID + WHERE + categoryxref.ID = {$this->ID} + GROUP BY + categories.CatName + ORDER BY + categories.CatName + ", SQL_ALL, SQL_ASSOC); + + $this->setVar('AddonCats',$this->db->record); + } +} +?> diff --git a/mozilla/webtools/addons/shared/lib/amo.class.php b/mozilla/webtools/addons/shared/lib/amo.class.php new file mode 100644 index 00000000000..dc56f3ce9f4 --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/amo.class.php @@ -0,0 +1,128 @@ +db =& $db; + $this->tpl =& $tpl; + } + + /** + * Set var. + * + * @param string $key name of object property to set + * @param mixed $val value to assign + * + * @return bool + */ + function setVar($key,$val) + { + $this->$key = $val; + return true; + } + + /** + * Set an array of variables based on a $db record. + * + * @param array $data associative array of data. + * + * @return bool + */ + function setVars($data) + { + if (is_array($data)) { + foreach ($data as $key=>$val) { + $this->setVar($key,$val); + } + return true; + } else { + return false; + } + } + + /** + * Get all category names. + */ + function getCats() + { + // Gather categories. + $this->db->query(" + SELECT + CategoryID, + CatName + FROM + categories + GROUP BY + CatName + ORDER BY + CatName + ", SQL_INIT, SQL_ASSOC); + + do { + $this->Cats[$this->db->record['CategoryID']] = $this->db->record['CatName']; + } while ($this->db->next(SQL_ASSOC)); + } + + /** + * Get all operating system names (platforms). Used to populate forms. + */ + function getPlatforms() + { + // Gather platforms.. + $this->db->query(" + SELECT + OSID, + OSName + FROM + os + ORDER BY + OSName + ", SQL_INIT, SQL_ASSOC); + + do { + $this->Platforms[$this->db->record['OSID']] = $this->db->record['OSName']; + } while ($this->db->next(SQL_ASSOC)); + + } + + /** + * Get all application names. Used to populate forms. + */ + function getApps() + { + // Gather aapplications. + $this->db->query(" + SELECT DISTINCT + AppID, + AppName + FROM + applications + WHERE + public_ver = 'YES' + GROUP BY + AppName + ", SQL_INIT, SQL_ASSOC); + + do { + $this->Apps[$this->db->record['AppID']] = $this->db->record['AppName']; + } while ($this->db->next(SQL_ASSOC)); + } +} +?> diff --git a/mozilla/webtools/addons/shared/lib/error.php b/mozilla/webtools/addons/shared/lib/error.php new file mode 100644 index 00000000000..67e986a3242 --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/error.php @@ -0,0 +1,28 @@ +assign( + array( + 'error'=>$errorMessage, + 'content'=>$errorTemplate, + 'backtrace'=>debug_backtrace() + ) + ); + + $tpl->display('inc/wrappers/nonav.tpl'); + exit; +} diff --git a/mozilla/webtools/addons/shared/lib/rdf.class.php b/mozilla/webtools/addons/shared/lib/rdf.class.php new file mode 100644 index 00000000000..f8ec1e3ff77 --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/rdf.class.php @@ -0,0 +1,1637 @@ +clear_element($e["parent"]); + $e["state"]=0; + $e["has_property_atributes"]=0; + $e["has_member_attributes"]=0; + $e["subject_type"]=0; + $e["subject"]=''; + $e["predicate"]=''; + $e["ordinal"]=0; + $e["members"]=0; + $e["data"]=''; + $e["xml_lang"]=''; + $e["bag_id"]=''; + $e["statements"]=0; + $e["statement_id"]=''; + + return $e; +} + +function _copy_element($source, &$destination ) +{ + if( $source ) + { + $destination["parent"] = $source; + $destination["state"] = $source["state"]; + $destination["xml_lang"] = $source["xml_lang"]; + } +} + +function _clear_element(&$e) +{ + $e["subject"]=''; + $e["predicate"]=''; + $e["data"]=''; + $e["bag_id"]=''; + $e["statement_id"]=''; + + if(isset($e["parent"])) { + if( $e["parent"] ) + { + if( $e["parent"]["xml_lang"] != $e["xml_lang"] ) + { + $e["xml_lang"]=''; + } + } + else + { + $e["xml_lang"]=''; + } + } else { + $e["xml_lang"]=''; + } + //memset( e, 0, strlen( _rdf_element ) ); + $e["parent"]=Array(); + $e["state"]=0; + $e["has_property_attributes"]=0; + $e["has_member_attributes"]=0; + $e["subject_type"]=0; + $e["subject"]=''; + $e["predicate"]=''; + $e["ordinal"]=0; + $e["members"]=0; + $e["data"]=''; + $e["xml_lang"]=''; + $e["bag_id"]=''; + $e["statements"]=0; + $e["statement_id"]=''; + +} + +function _push_element() +{ + if(!isset($this->rdf_parser["free"])) { + $this->rdf_parser["free"]=Array(); + } + if(count($this->rdf_parser["free"])>0) + { + $e = $this->rdf_parser["free"]; + if(isset($e["parent"])) { + $this->rdf_parser["free"] = $e["parent"]; + } else { + $this->rdf_parser["free"]=$this->_new_element(); + } + } + else + { + $e = $this->_new_element(); + } + if(!isset($this->rdf_parser["top"])) { + $this->rdf_parser["top"]=Array(); + } + $this->_copy_element( $this->rdf_parser["top"], $e ); + $this->rdf_parser["top"] = $e; +} + + +function _pop_element() +{ + $e = $this->rdf_parser["top"]; + $this->rdf_parser["top"] = $e["parent"]; + $this->_clear_element( $e ); + /* + if(isset($this->rdf_parser["free"])) { + $e["parent"] = $this->rdf_parser["free"]; + } else { + $e["parent"]=0; + } + */ + $this->rdf_parser["free"] = $e; +} + +function _delete_elements() +{ +} + + +function _is_rdf_property_attribute_resource($local_name ) +{ + return ( $local_name == RDF_TYPE ); +} + +function _is_rdf_property_attribute_literal($local_name ) +{ + return ( $local_name == RDF_VALUE ); +} + +function _is_rdf_ordinal( $local_name ) +{ + $ordinal = -1; + + //if($local_name{0}=='_') + if( $local_name{0} == '_' ) + { + $ordinal = substr($local_name,1) + 1 ; + } + + return ( $ordinal > 0 ) ? $ordinal : 0; +} + +function _is_rdf_property_attribute( $local_name ) +{ + return $this->_is_rdf_property_attribute_resource( $local_name ) + || $this->_is_rdf_property_attribute_literal( $local_name ); +} + +function _is_rdf_property_element( $local_name ) +{ + return ( $local_name == RDF_TYPE ) + || ( $local_name == RDF_SUBJECT ) + || ( $local_name == RDF_PREDICATE ) + || ( $local_name == RDF_OBJECT ) + || ( $local_name == RDF_VALUE ) + || ( $local_name == RDF_LI ) + || ( $local_name{0} == '_' ); +} + +function _istalnum($val) { + return ereg("[A-Za-z0-9]",$val); +} + +function _istalpha($val) { + return ereg("[A-Za-z]",$val); +} + + +function _is_absolute_uri($uri ) +{ + $result = false; + $uri_p=0; + if( $uri && $this->_istalpha( $uri{$uri_p} ) ) + { + ++$uri_p; + + while( ($uri_p_istalnum( $uri{$uri_p} ) + || ( $uri{$uri_p} == '+' ) + || ( $uri{$uri_p} == '-' ) + || ( $uri{$uri_p} == '.' ) ) ) + { + ++$uri_p; + } + + $result = ( $uri{$uri_p} == ':' ); + } + return $result; +} + + +/* +This function returns an associative array returning any of the various components of the URL that are present. This includes the +$arr=parse_url($url) +scheme - e.g. http +host +port +user +pass +path +query - after the question mark ? +fragment - after the hashmark # +*/ +function _parse_uri($uri,$buffer,$len,&$scheme,&$authority,&$path,&$query,&$fragment ) { + $parsed=parse_url($uri); + if(isset($parsed["scheme"])) { + $scheme=$parsed["scheme"];} else { + $scheme=''; + } + if(isset($parsed["host"])) { + $host=$parsed["host"];} else { + $host=''; + } + if(isset($parsed["host"])) { + $authority=$parsed["host"];} else { + $authority=''; + } + if(isset($parsed["path"])) { + $path=$parsed["path"];} else { + $path=''; + } + if(isset($parsed["query"])) { + $query=$parsed["query"];} else { + $query=''; + } + if(isset($parsed["fragment"])) { + $fragment=$parsed["fragment"];} else { + $fragment=''; + } + +} + + +function _resolve_uri_reference($base_uri,$reference_uri,&$buffer,$length ) +{ + $base_buffer=''; + $reference_buffer=''; + $path_buffer=''; + + $buffer = ''; + + $this->_parse_uri($reference_uri,$reference_buffer,strlen( $reference_buffer ),$reference_scheme,$reference_authority, + $reference_path,$reference_query,$reference_fragment ); + + if( $reference_scheme == '' + && $reference_authority == '' + && $reference_path == '' + && $reference_query == '' ) + { + $buffer=$base_uri; + + if( $reference_fragment != '' ) + { + $buffer.= "#" ; + $buffer.=$reference_fragment; + } + } + else if( $reference_scheme != '' ) + { + $buffer=$reference_uri; + } + else + { + $this->_parse_uri( + $base_uri, + $base_buffer, + strlen( $base_buffer ), + $base_scheme, + $base_authority, + $base_path, + $base_query, + $base_fragment ); + + $result_scheme = $base_scheme; + + if( $reference_authority != '' ) + { + $result_authority = $reference_authority; + } + else + { + $result_authority = $base_authority; + + if( $reference_path != '' + && ( ($reference_path{0} == '/') + || ($reference_path{0} == '\\') ) ) + { + $result_path = $reference_path; + } + else + { + $p = ''; + + $result_path = $path_buffer; + + $path_buffer=''; + + $p = strstr( $base_path, '/' ); + + if( !$p ) + { + $p = strstr( $base_path, '\\' ); + } + + if( $p ) + { + + $path_buffer.=$base_path; + + //while( s <= p ) + //{ + // *d++ = *s++; + //} + + //*d++ = 0; + + } + + if( $reference_path != '' ) + { + $path_buffer.=$reference_path; + } + + { + //remove all occurrences of "./" + //print($path_buffer); + $path_buffer=preg_replace("/\/\.\//","/",$path_buffer); + $path_buffer=preg_replace("/\/([^\/\.])*\/..$/","/",$path_buffer); + while(preg_match("/\.\./",$path_buffer)) { + $path_buffer=preg_replace("/\/([^\/\.]*)\/..\//","/",$path_buffer); + } + $path_buffer=preg_replace("/\.$/","",$path_buffer); + + } + + } + } + + // This replaces the C pointer assignament + + $result_path = $path_buffer; + if( $result_scheme != '' ) + { + $buffer=$result_scheme; + $buffer.=":"; + } + + if( $result_authority != '' ) + { + $buffer.="//"; + $buffer.=$result_authority; + } + + if( $result_path != '' ) + { + + $buffer.=$result_path; + } + + if( $reference_query != '' ) + { + $buffer.="?"; + $buffer.=$reference_query; + } + + if( $reference_fragment != '' ) + { + $buffer.="#"; + $buffer.=$reference_fragment; + } + } +} + + + +function is_valid_id($id ) +{ + $result = false; + $p = $id; + $p_p=0; + + if( $id != '' ) + { + if( $this->_istalpha( $p ) + || $p{0} == '_' + || $p{0} == ':' ) + { + $result = true; + + while( $result != false && ( $p{++$p_p} != 0 ) ) + { + if( ! ( $this->_istalnum( $p{$p_p} ) + || $p{$p_p} == '.' + || $p{$p_p} == '-' + || $p{$p_p} == '_' + || $p{$p_p} == ':' ) ) + { + $result = false; + } + } + } + } + + return $result; +} + +function _resolve_id($id,&$buffer,$length ) +{ + $id_buffer=''; + + if( $this->is_valid_id( $id ) == true ) + { + $id_buffer="#$id"; + } + else + { + $this->report_warning( "bad ID attribute: ".$id_buffer."#_bad_ID_attribute_"); + } + + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $id_buffer, $buffer, $length ); +} + +function _split_name($name, &$buffer, $len,&$namespace_uri, &$local_name ) +{ + + static $nul = 0; + $buffer=$name; + + + + + if( strstr( $buffer, NAMESPACE_SEPARATOR_CHAR ) ) + { + $cosas=explode(NAMESPACE_SEPARATOR_CHAR,$buffer); + $namespace_uri = $cosas[0]; + $local_name = $cosas[1]; + } + else + { + if( ( $buffer{ 0 } == 'x' ) + && ( $buffer{ 1 } == 'm' ) + && ( $buffer{ 2 } == 'l' ) + && ( $buffer{ 3 } == ':' ) ) + { + $namespace_uri = XML_NAMESPACE_URI; + $local_name = substr($buffer,4); + } + else + { + $namespace_uri = ''; + $local_name = $buffer; + } + } + + +} + +function _generate_anonymous_uri(&$buf, $len ) +{ + $id=''; + if(!isset($this->rdf_parser["anonymous_id"])) { + $this->rdf_parser["anonymous_id"]=0; + } + $this->rdf_parser["anonymous_id"]++; + + $id="#genid".$this->rdf_parser["anonymous_id"]; + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $id, $buf, $len ); + +} + +function _report_statement( $subject_type, $subject, $predicate, $ordinal, $object_type, $object, $xml_lang, $bag_id, $statements, $statement_id ) +{ + $statement_id_type = RDF_SUBJECT_TYPE_URI; + $statement_id_buffer=''; + $predicate_buffer=''; + + if( $this->rdf_parser["statement_handler"] ) + { + $this->rdf_parser["statement_handler"]($this->rdf_parser["user_data"],$subject_type,$subject,$predicate,$ordinal,$object_type,$object,$xml_lang ); + + if( $bag_id ) + { + if( $statements == '' ) + { + $this->_report_statement(RDF_SUBJECT_TYPE_URI, + $bag_id, + RDF_NAMESPACE_URI.RDF_TYPE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + RDF_NAMESPACE_URI.RDF_BAG, + '', + '', + '', + '' ); + } + + if( ! $statement_id ) + { + $statement_id_type = RDF_SUBJECT_TYPE_ANONYMOUS; + $this->_generate_anonymous_uri( + $statement_id_buffer, + strlen( $statement_id_buffer ) ); + $statement_id = $statement_id_buffer; + } + $statements++; + $predicate_buffer="RDF_NAMESPACE_URI_".$statements; + + $this->_report_statement( + RDF_SUBJECT_TYPE_URI, + $bag_id, + $predicate_buffer, + $statements, + RDF_OBJECT_TYPE_RESOURCE, + $statement_id, + '', + '', + '', + '' ); + } + + if( $statement_id ) + { + // rdf:type = rdf:Statement + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_TYPE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + RDF_NAMESPACE_URI.RDF_STATEMENT, + '', + '', + '', + '' ); + + // rdf:subject + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_SUBJECT, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $subject, + '', + '', + '', + '' ); + + // rdf:predicate + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_PREDICATE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $predicate, + '', + '', + '', + '' ); + + // rdf:object + $this->_report_statement( + $statement_id_type, + $statement_id, + RDF_NAMESPACE_URI.RDF_OBJECT, + 0, + $object_type, + $object, + '', + '', + '', + '' ); + } + } +} + +function _report_start_parse_type_literal() +{ + if( $this->rdf_parser["start_parse_type_literal_handler"] ) + { + $this->rdf_parser["start_parse_type_literal_handler"]( + $this->rdf_parser["user_data"] ); + } +} + +function _report_end_parse_type_literal() +{ + if( $this->rdf_parser["end_parse_type_literal_handler"] ) + { + $this->rdf_parser["end_parse_type_literal_handler"]( + $this->rdf_parser["user_data"] ); + } +} + +function _handle_property_attributes($subject_type, $subject, $attributes, $xml_lang, $bag_id, $statements ) +{ + $i=0; + + $attribute=''; + $predicate=''; + + $attribute_namespace_uri=''; + $attribute_local_name=''; + $attribute_value=''; + + $ordinal=0; + + for( $i = 0; isset($attributes[ $i ]); $i += 2 ) + { + $this->_split_name( + $attributes[ $i ], + $attribute, + strlen( $attribute ), + $attribute_namespace_uri, + $attribute_local_name ); + + $attribute_value = $attributes[ $i + 1 ]; + + $predicate=$attribute_namespace_uri; + $predicate.=$attribute_local_name; + + if( RDF_NAMESPACE_URI == $attribute_namespace_uri ) + { + if( $this->_is_rdf_property_attribute_literal( $attribute_local_name ) ) + { + $this->_report_statement( + $subject_type, + $subject, + $predicate, + 0, + RDF_OBJECT_TYPE_LITERAL, + $attribute_value, + $xml_lang, + $bag_id, + $statements, + '' ); + } + else if( $this->_is_rdf_property_attribute_resource( $attribute_local_name ) ) + { + $this->_report_statement( + $subject_type, + $subject, + $predicate, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $attribute_value, + '', + $bag_id, + $statements, + '' ); + } + else if( ( $ordinal = $this->_is_rdf_ordinal( $attribute_local_name ) ) != 0 ) + { + $this->_report_statement( + $subject_type, + $subject, + $predicate, + $ordinal, + RDF_OBJECT_TYPE_LITERAL, + $attribute_value, + $xml_lang, + $bag_id, + $statements, + '' ); + } + } + else if( XML_NAMESPACE_URI == $attribute_namespace_uri ) + { + //do nothing + } + else if( $attribute_namespace_uri ) + { + // is it required that property attributes be in an explicit namespace? + + $this->_report_statement( + $subject_type, + $subject, + $predicate, + 0, + RDF_OBJECT_TYPE_LITERAL, + $attribute_value, + $xml_lang, + $bag_id, + $statements, + '' ); + } + } +} + +function _report_start_element( $name, $attributes ) +{ + if( isset($this->rdf_parser["start_element_handler"]) ) + { + $this->rdf_parser["start_element_handler"]( + $this->rdf_parser["user_data"], + $name, + $attributes ); + } +} + +function _report_end_element( $name ) +{ + if( isset($this->rdf_parser["end_element_handler"]) ) + { + $this->rdf_parser["end_element_handler"]( + $this->rdf_parser["user_data"], + $name ); + } +} + +function _report_character_data($s,$len ) +{ + if( isset($this->rdf_parser["character_data_handler"]) ) + { + $this->rdf_parser["character_data_handler"]( + $this->rdf_parser["user_data"], + $s, + $len ); + } +} + +function _report_warning( $warning) +{ + + // rdf_parser->top->state = IN_UNKNOWN; + + if( isset($this->rdf_parser["warning_handler"]) ) + { + $this->rdf_parser["warning_handler"] ( + $warning); + } +} + +function _handle_resource_element( $namespace_uri, $local_name, $attributes, $parent ) +{ + $subjects_found = 0; + $aux=$attributes; + $aux2=Array(); + foreach($attributes as $atkey=>$atvalue) { + $aux2[]=$atkey; + $aux2[]=$atvalue; + } + $attributes=$aux2; + $id = ''; + $about = ''; + $about_each = ''; + $about_each_prefix = ''; + + $bag_id = ''; + + $i=0; + + $attribute=''; + + $attribute_namespace_uri=''; + $attribute_local_name=''; + $attribute_value=''; + + $id_buffer=''; + + $type=''; + + $this->rdf_parser["top"]["has_property_attributes"] = false; + $this->rdf_parser["top"]["has_member_attributes"] = false; + + // examine each attribute for the standard RDF "keywords" + for( $i = 0; isset($attributes[$i]); $i += 2 ) + { + $this->_split_name( + $attributes[ $i ], + $attribute, + strlen( $attribute ), + $attribute_namespace_uri, + $attribute_local_name ); + + $attribute_value = $attributes[ $i + 1 ]; + + // if the attribute is not in any namespace + // or the attribute is in the RDF namespace + if( ( $attribute_namespace_uri == '' ) + || ( $attribute_namespace_uri == RDF_NAMESPACE_URI )) + { + if( $attribute_local_name == RDF_ID ) + { + $id = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_ABOUT ) + { + $about = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_ABOUT_EACH ) + { + $about_each = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_ABOUT_EACH_PREFIX ) + { + $about_each_prefix = $attribute_value; + ++$subjects_found; + } + else if( $attribute_local_name == RDF_BAG_ID) + { + $bag_id = $attribute_value; + } + else if( $this->_is_rdf_property_attribute( $attribute_local_name ) ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + else if( $this->_is_rdf_ordinal( $attribute_local_name ) ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + $this->rdf_parser["top"]["has_member_attributes"] = true; + } + else + { + $this->_report_warning( + "unknown or out of context rdf attribute:".$attribute_local_name ); + } + } + else if( $attribute_namespace_uri == XML_NAMESPACE_URI ) + { + if( $attribute_local_name == XML_LANG ) + { + $this->rdf_parser["top"]["xml_lang"] = $attribute_value; + } + } + else if( $attribute_namespace_uri ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + } + + // if no subjects were found, generate one. + if( $subjects_found == 0 ) + { + $this->_generate_anonymous_uri( $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["subject"]=$id_buffer; + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_ANONYMOUS; + } + else if( $subjects_found > 1 ) + { + $this->_report_warning( + "ID, about, aboutEach, and aboutEachPrefix are mutually exclusive" ); + return; + } + else if( $id ) + { + $this->_resolve_id( $id, $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_URI; + $this->rdf_parser["top"]["subject"]=$id_buffer; + } + else if( $about ) + { + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $about, $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_URI; + $this->rdf_parser["top"]["subject"]=$id_buffer; + } + else if( $about_each ) + { + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_DISTRIBUTED; + $this->rdf_parser["top"]["subject"]=$about_each; + } + else if( $about_each_prefix ) + { + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_PREFIX; + $this->rdf_parser["top"]["subject"]=$about_each_prefix; + } + + // if the subject is empty, assign it the document uri + if( $this->rdf_parser["top"]["subject"] == '' ) + { + $len = 0; + + $this->rdf_parser["top"]["subject"]=$this->rdf_parser["base_uri"]; + + // now remove the trailing '#' + + $len = strlen( $this->rdf_parser["top"]["subject"]); + + if( $len > 0 ) + { + //$rdf_parser["top"]["subject"][" len - 1 "] = 0; + } + } + + if( $bag_id ) + { + $this->_resolve_id( $bag_id, $id_buffer, strlen( $id_buffer ) ); + $this->rdf_parser["top"]["bag_id"]=$id_buffer; + } + + // only report the type for non-rdf:Description elements. + if( ($local_name != RDF_DESCRIPTION ) + || ( $namespace_uri != RDF_NAMESPACE_URI ) ) + { + $type=$namespace_uri; + $type.=$local_name; + + $this->_report_statement( + $this->rdf_parser["top"]["subject_type"], + $this->rdf_parser["top"]["subject"], + RDF_NAMESPACE_URI.RDF_TYPE, + 0, + RDF_OBJECT_TYPE_RESOURCE, + $type, + '', + $this->rdf_parser["top"]["bag_id"], + $this->rdf_parser["top"]["statements"], + '' ); + + } + + // if this element is the child of some property, + // report the appropriate statement. + if( $parent ) + { + $this->_report_statement( + $parent["parent"]["subject_type"], + $parent["parent"]["subject"], + $parent["predicate"], + $parent["ordinal"], + RDF_OBJECT_TYPE_RESOURCE, + $this->rdf_parser["top"]["subject"], + '', + $parent["parent"]["bag_id"], + $parent["parent"]["statements"], + $parent["statement_id"] ); + + } + + if( $this->rdf_parser["top"]["has_property_attributes"] ) + { + $this->_handle_property_attributes( + $this->rdf_parser["top"]["subject_type"], + $this->rdf_parser["top"]["subject"], + $attributes, + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["bag_id"], + $this->rdf_parser["top"]["statements"] ); + } +} + +function _handle_property_element( &$namespace_uri, &$local_name, &$attributes ) +{ + $buffer=''; + + $i=0; + + $aux=$attributes; + $aux2=Array(); + foreach($attributes as $atkey=>$atvalue) { + $aux2[]=$atkey; + $aux2[]=$atvalue; + } + $attributes=$aux2; + + $attribute_namespace_uri=''; + $attribute_local_name=''; + $attribute_value = ''; + + $resource = ''; + $statement_id = ''; + $bag_id = ''; + $parse_type = ''; + + $this->rdf_parser["top"]["ordinal"] = 0; + + if( $namespace_uri == RDF_NAMESPACE_URI ) + { + if( ($this->rdf_parser["top"]["ordinal"] = ( $this->_is_rdf_ordinal( $local_name ) ) != 0 ) ) + { + if( $this->rdf_parser["top"]["ordinal"] > $this->rdf_parser["top"]["parent"]["members"] ) + { + $this->rdf_parser["top"]["parent"]["members"] = $this->rdf_parser["top"]["ordinal"]; + } + } + else if( ! $this->_is_rdf_property_element( $local_name ) ) + { + $this->_report_warning( + "unknown or out of context rdf property element: ".$local_name ); + return; + } + } + + $buffer=$namespace_uri; + + if( ( $namespace_uri == RDF_NAMESPACE_URI ) + && ( $local_name == RDF_LI ) ) + { + //$ordinal=''; + $this->rdf_parser["top"]["parent"]["members"]++; + $this->rdf_parser["top"]["ordinal"] = $this->rdf_parser["top"]["parent"]["members"]; + + + $this->rdf_parser["top"]["ordinal"]=$this->rdf_parser["top"]["ordinal"]; + //$ordinal{ 0 } = '_' ; + + $buffer.='_'.$this->rdf_parser["top"]["ordinal"]; + } + else + { + $buffer.=$local_name; + } + + $this->rdf_parser["top"]["predicate"]=$buffer; + + $this->rdf_parser["top"]["has_property_attributes"] = false; + $this->rdf_parser["top"]["has_member_attributes"] = false; + + for( $i = 0; isset($attributes[$i]); $i += 2 ) + { + $this->_split_name( + $attributes[$i], + $buffer, + strlen( $buffer ), + $attribute_namespace_uri, + $attribute_local_name ); + + $attribute_value = $attributes[$i + 1]; + + // if the attribute is not in any namespace + // or the attribute is in the RDF namespace + if( ( $attribute_namespace_uri == '' ) + || ( $attribute_namespace_uri == RDF_NAMESPACE_URI ) ) + { + if( ( $attribute_local_name == RDF_ID ) ) + { + $statement_id = $attribute_value; + } + else if( $attribute_local_name == RDF_PARSE_TYPE ) + { + $parse_type = $attribute_value; + } + else if( $attribute_local_name == RDF_RESOURCE ) + { + $resource = $attribute_value; + } + else if( $attribute_local_name == RDF_BAG_ID ) + { + $bag_id = $attribute_value; + } + else if( $this->_is_rdf_property_attribute( $attribute_local_name ) ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + else + { + $this->_report_warning( + "unknown rdf attribute: ".$attribute_local_name ); + return; + } + } + else if( $attribute_namespace_uri == XML_NAMESPACE_URI ) + { + if( $attribute_local_name == XML_LANG ) + { + $this->rdf_parser["top"]["xml_lang"] = $attribute_value; + } + } + else if( $attribute_namespace_uri ) + { + $this->rdf_parser["top"]["has_property_attributes"] = true; + } + } + + // this isn't allowed by the M&S but I think it should be + if( $statement_id && $resource ) + { + $this->_report_warning( + "rdf:ID and rdf:resource are mutually exclusive" ); + return; + } + + if( $statement_id ) + { + $this->_resolve_id($statement_id, $buffer, strlen( $buffer ) ); + $this->rdf_parser["top"]["statement_id"]=$buffer; + } + + if( $parse_type ) + { + if( $resource ) + { + $this->_report_warning( + "property elements with rdf:parseType do not allow rdf:resource" ); + return; + } + + if( $bag_id ) + { + $this->_report_warning( + "property elements with rdf:parseType do not allow rdf:bagID" ); + return; + } + + if( $this->rdf_parser["top"]["has_property_attributes"] ) + { + $this->_report_warning( + "property elements with rdf:parseType do not allow property attributes"); + return; + } + + if( $attribute_value == RDF_PARSE_TYPE_RESOURCE ) + { + $this->_generate_anonymous_uri( $buffer, strlen( $buffer ) ); + + // since we are sure that this is now a resource property we can report it + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + 0, + RDF_OBJECT_TYPE_RESOURCE, + $buffer, + '', + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $statement_id ); + + $this->_push_element( ); + + $this->rdf_parser["top"]["state"] = IN_PROPERTY_PARSE_TYPE_RESOURCE; + $this->rdf_parser["top"]["subject_type"] = RDF_SUBJECT_TYPE_ANONYMOUS; + $this->rdf_parser["top"]["subject"]=$buffer; + $this->rdf_parser["top"]["bag_id"]=''; + } + else + { + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + 0, + RDF_OBJECT_TYPE_XML, + '', + '', + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $statement_id ); + + $this->rdf_parser["top"]["state"] = IN_PROPERTY_PARSE_TYPE_LITERAL; + $this->_report_start_parse_type_literal(); + } + } + else if( $resource || $bag_id || $this->rdf_parser["top"]["has_property_attributes"] ) + { + + + if( $resource != '' ) + { + $subject_type = RDF_SUBJECT_TYPE_URI; + $this->_resolve_uri_reference( $this->rdf_parser["base_uri"], $resource, $buffer, strlen( $buffer ) ); + } + else + { + $subject_type = RDF_SUBJECT_TYPE_ANONYMOUS; + $this->_generate_anonymous_uri( buffer, strlen( $buffer ) ); + } + + $this->rdf_parser["top"]["state"] = IN_PROPERTY_EMPTY_RESOURCE; + + // since we are sure that this is now a resource property we can report it. + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + $this->rdf_parser["top"]["ordinal"], + RDF_OBJECT_TYPE_RESOURCE, + $buffer, + '', + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + '' ); // should we allow IDs? + + if( $bag_id ) + { + $this->_resolve_id( $bag_id, $buffer, strlen( $buffer ) ); + $this->rdf_parser["top"]["bag_id"]=$buffer; + } + + if( $this->rdf_parser["top"]["has_property_attributes"] ) + { + $this->_handle_property_attributes( + $subject_type, + $buffer, + $attributes, + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["bag_id"], + $this->rdf_parser["top"]["statements"] ); + } + } +} + + +function _start_element_handler($parser, $name, $attributes ) +{ + + + $buffer=''; + + $namespace_uri=''; + $local_name=''; + +/* + if( rdf_parser->top != '' && rdf_parser->top->state != IN_TOP_LEVEL ) + { + ++rdf_parser->anonymous_id; + } +*/ + + $this->_push_element(); + + + $this->_split_name( + $name, + $buffer, + strlen( $buffer ), + $namespace_uri, + $local_name ); + + switch( $this->rdf_parser["top"]["state"] ) + { + case IN_TOP_LEVEL: + if( RDF_NAMESPACE_URI.NAMESPACE_SEPARATOR_STRING.RDF_RDF == $name ) + { + $this->rdf_parser["top"]["state"] = IN_RDF; + } + else + { + $this->_report_start_element( $name, $attributes ); + } + break; + case IN_RDF: + $this->rdf_parser["top"]["state"] = IN_DESCRIPTION; + $this->_handle_resource_element( $namespace_uri, $local_name, $attributes, '' ); + break; + case IN_DESCRIPTION: + case IN_PROPERTY_PARSE_TYPE_RESOURCE: + $this->rdf_parser["top"]["state"] = IN_PROPERTY_UNKNOWN_OBJECT; + $this->_handle_property_element( $namespace_uri, $local_name, $attributes ); + break; + case IN_PROPERTY_UNKNOWN_OBJECT: + /* if we're in a property with an unknown object type and we encounter + an element, the object must be a resource, */ + $this->rdf_parser["top"]["data"]=''; + $this->rdf_parser["top"]["parent"]["state"] = IN_PROPERTY_RESOURCE; + $this->rdf_parser["top"]["state"] = IN_DESCRIPTION; + $this->_handle_resource_element( + $namespace_uri, + $local_name, + $attributes, + $this->rdf_parser["top"]["parent"] ); + break; + case IN_PROPERTY_LITERAL: + $this->_report_warning( "no markup allowed in literals" ); + break; + case IN_PROPERTY_PARSE_TYPE_LITERAL: + $this->rdf_parser["top"]["state"] = IN_XML; + /* fall through */ + case IN_XML: + $this->_report_start_element( $name, $attributes ); + break; + case IN_PROPERTY_RESOURCE: + $this->_report_warning( + "only one element allowed inside a property element" ); + break; + case IN_PROPERTY_EMPTY_RESOURCE: + $this->_report_warning( + "no content allowed in property with rdf:resource, rdf:bagID, or property attributes" ); + break; + case IN_UNKNOWN: + break; + } +} + +/* + this is only called when we're in the IN_PROPERTY_UNKNOWN_OBJECT state. + the only time we won't know what type of object a statement has is + when we encounter property statements without property attributes or + content: + + + + + + notice that the state doesn't switch to IN_PROPERTY_LITERAL when + there is only whitespace between the start and end tags. this isn't + a very useful statement since the object is anonymous and can't + have any statements with it as the subject but it is allowed. +*/ + +function _end_empty_resource_property() +{ + $buffer=''; + + $this->_generate_anonymous_uri($buffer, strlen( $buffer ) ); + + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + $this->rdf_parser["top"]["ordinal"], + RDF_OBJECT_TYPE_RESOURCE, + $buffer, + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $this->rdf_parser["top"]["statement_id"] ); +} + +/* + property elements with text only as content set the state to + IN_PROPERTY_LITERAL. as character data is received from expat, + it is saved in a buffer and reported when the end tag is + received. +*/ +function _end_literal_property() +{ + if(!isset($this->rdf_parser["top"]["statement_id"])) { + $this->rdf_parser["top"]["statement_id"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["subject_type"])) { + $this->rdf_parser["top"]["parent"]["subject_type"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["subject"])) { + $this->rdf_parser["top"]["parent"]["subject"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["bag_id"])) { + $this->rdf_parser["top"]["parent"]["bag_id"]=''; + } + if(!isset($this->rdf_parser["top"]["parent"]["statements"])) { + $this->rdf_parser["top"]["parent"]["statements"]=0; + } + if(!isset($this->rdf_parser["top"]["predicate"])) { + $this->rdf_parser["top"]["predicate"]=''; + } + if(!isset($this->rdf_parser["top"]["ordinal"])) { + $this->rdf_parser["top"]["ordinal"]=0; + } + $this->_report_statement( + $this->rdf_parser["top"]["parent"]["subject_type"], + $this->rdf_parser["top"]["parent"]["subject"], + $this->rdf_parser["top"]["predicate"], + $this->rdf_parser["top"]["ordinal"], + RDF_OBJECT_TYPE_LITERAL, + $this->rdf_parser["top"]["data"], + $this->rdf_parser["top"]["xml_lang"], + $this->rdf_parser["top"]["parent"]["bag_id"], + $this->rdf_parser["top"]["parent"]["statements"], + $this->rdf_parser["top"]["statement_id"] ); +} + +function _end_element_handler( $parser, $name ) +{ + + + switch( $this->rdf_parser["top"]["state"] ) + { + case IN_TOP_LEVEL: + /* fall through */ + case IN_XML: + $this->_report_end_element( $name ); + break; + case IN_PROPERTY_UNKNOWN_OBJECT: + $this->_end_empty_resource_property(); + break; + case IN_PROPERTY_LITERAL: + $this->_end_literal_property( ); + break; + case IN_PROPERTY_PARSE_TYPE_RESOURCE: + $this->_pop_element( ); + break; + case IN_PROPERTY_PARSE_TYPE_LITERAL: + $this->_report_end_parse_type_literal(); + break; + case IN_RDF: + case IN_DESCRIPTION: + case IN_PROPERTY_RESOURCE: + case IN_PROPERTY_EMPTY_RESOURCE: + case IN_UNKNOWN: + break; + } + + $this->_pop_element(); +} + +function _character_data_handler( $parser,$s) +{ + $len=strlen($s); + switch( $this->rdf_parser["top"]["state"] ) + { + case IN_PROPERTY_LITERAL: + case IN_PROPERTY_UNKNOWN_OBJECT: + if( isset($this->rdf_parser["top"]["data"]) ) + { + $n = strlen( $this->rdf_parser["top"]["data"] ); + $this->rdf_parser["top"]["data"].= $s; + + } + else + { + $this->rdf_parser["top"]["data"]=$s; + } + + if( $this->rdf_parser["top"]["state"] == IN_PROPERTY_UNKNOWN_OBJECT ) + { + /* look for non-whitespace */ + for( $i = 0; (( $i < $len ) && ( ereg(" |\n|\t",$s{ $i }) )); $i++ ); + $i++; + /* if we found non-whitespace, this is a literal */ + if( $i < $len ) + { + $this->rdf_parser["top"]["state"] = IN_PROPERTY_LITERAL; + } + } + + break; + case IN_TOP_LEVEL: + case IN_PROPERTY_PARSE_TYPE_LITERAL: + case IN_XML: + $this->_report_character_data( + $s, + strlen($s) ); + break; + case IN_RDF: + case IN_DESCRIPTION: + case IN_PROPERTY_RESOURCE: + case IN_PROPERTY_EMPTY_RESOURCE: + case IN_PROPERTY_PARSE_TYPE_RESOURCE: + case IN_UNKNOWN: + break; + } +} + +/* public functions */ + + +function rdf_parser_create( $encoding ) +{ + + $parser = xml_parser_create_ns( $encoding, NAMESPACE_SEPARATOR_CHAR ); + xml_parser_set_option($parser,XML_OPTION_CASE_FOLDING,0); + $this->rdf_parser["xml_parser"] = $parser; + + xml_set_object($this->rdf_parser["xml_parser"], $this); + xml_set_element_handler( $this->rdf_parser["xml_parser"], "_start_element_handler", "_end_element_handler" ); + xml_set_character_data_handler( $this->rdf_parser["xml_parser"], "_character_data_handler" ); + + return $this->rdf_parser; +} + +function rdf_parser_free( ) +{ + $z=3; +// xml_parser_free( $this->rdf_parser["xml_parser"] ); + + $this->rdf_parser["base_uri"]=''; + + $this->_delete_elements( $this->rdf_parser ); + + unset( $this->rdf_parser ); +} + +function rdf_set_user_data( &$user_data ) +{ + $this->rdf_parser["user_data"] = &$user_data; +} + +function rdf_get_user_data( ) +{ + return ( $this->rdf_parser["$user_data"] ); +} + +function rdf_set_statement_handler($handler ) +{ + $this->rdf_parser["statement_handler"] = $handler; +} + +function rdf_set_parse_type_literal_handler($start,$end ) +{ + $this->rdf_parser["start_parse_type_literal_handler"] = $start; + $this->rdf_parser["end_parse_type_literal_handler"] = $end; +} + +function rdf_set_element_handler($start,$end) +{ + $this->rdf_parser["_start_element_handler"] = $start; + $this->rdf_parser["_end_element_handler"] = $end; +} + +function rdf_set_character_data_handler( $handler) +{ + $this->rdf_parser["_character_data_handler"] = $handler; +} + +function rdf_set_warning_handler($handler ) +{ + $this->rdf_parser["warning_handler"] = $handler; +} + +function rdf_parse( $s, $len, $is_final ) +{ + return XML_Parse( $this->rdf_parser["xml_parser"], $s, $is_final ); +} + +function rdf_get_xml_parser() +{ + return ( $this->rdf_parser["xml_parser"]); +} + +function rdf_set_base($base ) +{ + + //tcscpy( buffer, base ); + +/* + if( buffer[" tcslen( buffer ) - 1 "] != T( '#' ) ) + { + tcscat( buffer, T( "#" ) ); + } +*/ + + /* check for out of memory */ + $this->rdf_parser["base_uri"]=$base; + + return 0; +} + +function rdf_get_base() +{ + return $this->rdf_parser["base_uri"]; +} + +function rdf_resolve_uri($uri_reference,&$buffer) +{ + _resolve_uri_reference( $this->rdf_parser["base_uri"], $uri_reference, $buffer, strlen($buffer) ); +} + +} + + + + + + + + + +} +?> \ No newline at end of file diff --git a/mozilla/webtools/addons/shared/lib/rss.class.php b/mozilla/webtools/addons/shared/lib/rss.class.php new file mode 100644 index 00000000000..e69de29bb2d diff --git a/mozilla/webtools/addons/shared/lib/session.class.php b/mozilla/webtools/addons/shared/lib/session.class.php new file mode 100644 index 00000000000..92b88d7e7de --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/session.class.php @@ -0,0 +1,220 @@ +db = $aDb; + } + + /** + * Destructor + * Required to force a flush of the session data to the database + * before the class disappears. + * @link http://bugs.php.net/bug.php?id=33772 + */ + function __destruct() + { + session_write_close(); + } + + /** + * Prepare variables for use in SQL + * @param aArray array hash of variables to clean + * @return array a new hash with SQL cleaned values, FALSE on failure + * + * TODO: should this be here or should we extend SQL to handle hashes like + * this since it happens so often? + */ + function _prepareForSql($in) + { + /** + * If we don't have a database connection then we + * can't really continue + */ + if (empty($this->db)) + return FALSE; + + $out = array(); + foreach ($in as $key => $value) + { + // TODO: when the SQL class gets it's own escapeSimple then + // change this to use that instead + $out[$key] = $this->db->db->escapeSimple($value); + } + + return $out; + } + + /** + * Open a new session + * + * @param $aPath string a path to be used to store the session + * @param $aName string a filename to be used to store the session + * @return boolean TRUE on success, FALSE otherwise + */ + function _open($aPath, $aName) + { + /** + * Return FALSE if we don't have a database to use + */ + + return empty($this->db) == FALSE; + } + + /** + * Close a session + * @return boolean TRUE on success, FALSE otherwise + */ + function _close() + { + return TRUE; + } + + /** + * Read some data from a session + * @param $aSessId string a session Id + * @return string the data, or an empty string on failure + */ + function _read($aSessId) + { + if (! strlen($aSessId)) + return ''; + + /** + * If for some reason we don't have a database handle, then + * we can't really continue here + */ + if (empty($this->db)) + return ''; + + /** + * Clean the arguments for SQL + */ + $clean = $this->_prepareForSql(array('SessId' => $aSessId)); + + /** + * We only want the data, don't care about anything else + */ + $sql = sprintf("SELECT SESSIONDATA FROM %s WHERE SESSIONID='%s'", $this->dbTable, $clean['SessId']); + $data = ''; + + if ($this->db->query($sql, SQL_INIT, SQL_ASSOC)) + { + /** + * Anything other than 1 row should indicate an error, so don't + * propagate this but rather handle it as if there was no data + * at all. + */ + if ($this->db->result->numRows() == 1) + { + $data = $this->db->record['SESSIONDATA']; + } + $this->db->result->free(); + } + + return $data; + } + + /** + * Write some data to the session + * @param $aSessId string a session Id + * @param $aSessData string the encoded [serialized?] session data to store + */ + function _write($aSessId, $aSessData) + { + /** + * If for some reason we don't have a database handle, then + * we can't really continue here + */ + if (empty($this->db)) + return FALSE; + + /** + * Clean the arguments for SQL + */ + $clean = $this->_prepareForSql(array('SessId' => $aSessId, 'SessData' => $aSessData)); + + /** + * Due to the handy REPLACE [INTO] syntax, we don't care if there is already + * a record there or not, this one statment will insert or replace as needed. + * HOWEVER: + * Should we ever try to use the session Id as a foreign key in the database + * then this will cause a referential constraint failure, as the REPLACE will + * include a DELETE in cases where the record already exists. Additionally, if + * we store anything other than the SESSIONDATA in the table which doesn't have + * an automatic default then it will get lost between writes unless it is included + * in the statement. + */ + $sql = sprintf("REPLACE %s SET SESSIONID='%s', SESSIONDATA='%s'", $this->dbTable, $clean['SessId'], $clean['SessData']); + return $this->db->query($sql, SQL_NONE); + } + + /** + * Destroy a session + * @param $aSessId string a session Id + * @return boolean TRUE on success, FALSE otherwise + */ + function _destroy($aSessId) + { + /** + * If for some reason we don't have a database handle, then + * we can't really continue here + */ + if (empty($this->db)) + return FALSE; + + /** + * Clean the arguments for SQL + */ + $clean = $this->_prepareForSql(array('SessId' => $aSessId)); + + $sql = sprintf("DELETE FROM %s WHERE SESSIONID='%s'", $this->dbTable, $clean['SessId']); + + return $this->db->db->query($sql); + } + + /** + * Garbage collector + * @param $aLifeTime number maximum age of a session to retain + * @return boolean TRUE on success, FALSE otherwise + */ + function _gc($sLifeTime) + { + return TRUE; + } +} +?> diff --git a/mozilla/webtools/addons/shared/lib/sql.class.php b/mozilla/webtools/addons/shared/lib/sql.class.php new file mode 100644 index 00000000000..360ca9195ff --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/sql.class.php @@ -0,0 +1,110 @@ + + */ + +// Define query types. +define('SQL_NONE', 1); +define('SQL_ALL', 2); +define('SQL_INIT', 3); + +// Define the query formats. +define('SQL_ASSOC', 1); +define('SQL_INDEX', 2); + +class SQL { + + var $db = null; + var $result = null; + var $error = null; + var $record = null; + + /** + * Class constructor. + */ + function SQL() { } + + /** + * Connect to the database. + * + * @param string $dsn the data source name + * @return bool + */ + function connect($dsn) { + $this->db =& DB::connect($dsn); + + if(PEAR::isError($this->db)) { + $this->error =& $this->db->getMessage(); + return false; + } + return true; + } + + /** + * Disconnect from the database. + */ + function disconnect() { + $this->db->disconnect(); + } + + /** + * Query the database. + * + * @param string $query the SQL query + * @param string $type the type of query + * @param string $format the query format + */ + function query($query, $type = SQL_NONE, $format = SQL_INDEX) { + + $this->record = array(); + $_data = array(); + + // Determine fetch mode (index or associative). + $_fetchmode = ($format == SQL_ASSOC) ? DB_FETCHMODE_ASSOC : null; + + $this->result = $this->db->query($query); + if (DB::isError($this->result)) { + $this->error = $this->result->getMessage(); + return false; + } + switch ($type) { + case SQL_ALL: + // Get all the records. + while($_row = $this->result->fetchRow($_fetchmode)) { + $_data[] = $_row; + } + $this->result->free(); + $this->record = $_data; + break; + case SQL_INIT: + // Get the first record. + $this->record = $this->result->fetchRow($_fetchmode); + break; + case SQL_NONE: + default: + // Records will be looped over with next(). + break; + } + return true; + } + + /** + * Select next row in result. + * @param string $format the query format + */ + function next($format = SQL_INDEX) { + // Fetch mode (index or associative). + $_fetchmode = ($format == SQL_ASSOC) ? DB_FETCHMODE_ASSOC : null; + if ($this->record = $this->result->fetchRow($_fetchmode)) { + return true; + } else { + $this->result->free(); + return false; + } + + } +} +?> diff --git a/mozilla/webtools/addons/shared/lib/systemMessage.php b/mozilla/webtools/addons/shared/lib/systemMessage.php new file mode 100644 index 00000000000..6a3157573c1 --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/systemMessage.php @@ -0,0 +1,33 @@ +query to pull messages (if they exist and are flagged as active) + * @todo add db tables to SQL schema + */ + +#define PAGE_TYPE_FRONT_PAGE 1 +#define PAGE_TYPE_DEVELOPER_PAGE 2 +#define PAGE_TYPE_LIST_PAGE 4 +#define PAGE_TYPE_DETAIL_PAGE 8 + +// these values can be done as a DB table so they can be controlled and edited by site admins without access to the webserver itself +function getSystemMessageData() { + $messageData['header'] = 'Want to get involved?'; + $messageData['text'] = 'We are looking for volunteers to help us with UMO. We are in need of PHP developers to help with redesigning the site, and people to review extensions and themes that get submitted to UMO. We especially need Mac and Thunderbird users. If you are interested in being a part of this exciting project, please send information such as your full name, timezone and experience to umo-reviewer@mozilla.org. Also, please join us in #umo on irc.mozilla.org to start getting a feeling for what\'s up or for a more informal chat.'; + $messageData['pageType'] = 1; + + return $messageData; +} + +function showSystemMessage($pageType) { + $messageData = getSystemMessageData(); + if ($messageData['pageType'] & $pageType) { + $smarty->assign("systemMessage", $messageData); + } +} + +// USAGE: +// showSystemMessage(PAGE_TYPE_FRONT_PAGE); should be somewhere in the script, with the +// appropriate page type + +?> diff --git a/mozilla/webtools/addons/shared/lib/user.class.php b/mozilla/webtools/addons/shared/lib/user.class.php new file mode 100644 index 00000000000..d047394b4f5 --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/user.class.php @@ -0,0 +1,92 @@ +db =& $db; + $this->tpl =& $tpl; + + // If $ID is set, attempt to retrieve data. + if (!empty($UserID)) { + $this->setVar('UserID',$UserID); + $this->getUser(); + $this->GetAddons(); + } + } + + /** + * Get user information from singular record. + */ + function getUser() + { + $this->db->query(" + SELECT + UserName, + UserEmail, + UserWebsite, + UserMode, + UserTrusted, + UserEmailHide, + UserLastLogin + FROM + userprofiles + WHERE + UserID = {$this->UserID} + ", SQL_INIT, SQL_ASSOC); + + if (!empty($this->db->record)) { + $this->setVars($this->db->record); + } + } + + /** + * Get addons for this author. + */ + function getAddons() + { + // Gather addons metadata, user info. + $this->db->query(" + SELECT + main.ID, + main.Name, + main.Description + FROM + main + INNER JOIN authorxref ON authorxref.ID = main.ID + INNER JOIN userprofiles ON userprofiles.UserID = authorxref.UserID + WHERE + userprofiles.UserID = '{$this->UserID}' + ", SQL_ALL, SQL_ASSOC); + + if (!empty($this->db->record)) { + $this->setVar('AddOns',$this->db->record); + } + } +} +?> diff --git a/mozilla/webtools/addons/shared/lib/version.class.php b/mozilla/webtools/addons/shared/lib/version.class.php new file mode 100644 index 00000000000..5e60b317cce --- /dev/null +++ b/mozilla/webtools/addons/shared/lib/version.class.php @@ -0,0 +1,148 @@ +parseString($aVersionString); + } + } + + /** + * Parse a version string into useful chunks. + * + * @param string $aVersionString FVF conformant version string + */ + function parseString($aVersionString) { + assert(strlen($aVersionString)); + + // in case we're being re-used + $this->major = NULL; + $this->minor = NULL; + $this->release = NULL; + $this->build = NULL; + $this->plus = NULL; + + // holder for the chunks, to be filled by preg_match + $matches = array(); + + if (preg_match('/^(\d+)(?:\.(\d+))?(?:\.(\d+))?(?:\.(\d+)([a-zA-Z0-9]+)?)?$/', $aVersionString, $matches)) { + + if (isset($matches[1])) { + $this->major = intval($matches[1]); + + if (isset($matches[2])) { + $this->minor = intval($matches[2]); + + if (isset($matches[3])) { + $this->release = intval($matches[3]); + + if (isset($matches[4])) { + $this->build = intval($matches[4]); + + if (isset($matches[5])) { + $this->plus = $matches[5]; + } + } + } + } + } + } + + assert($aVersionString == $this->toString()); + } + + /** + * Is this a valid version + * + * @return boolean TRUE if the instance represents a valid version + * FALSE otherwise + * + * @todo this may or may not be required. it simply relies on the + * fact that major is not optional. any valid string would + * have been parsed, and major set + */ + function isValid() { + return isset($this->major); + } + + /** + * Static method to compare one Version to another Version + * + * @param a a Version + * @param a a Version + * @returns < 0 if a < b + * = 0 if a == b + * > 0 if a > b + */ + function compare($a, $b) { + assert(is_a($a, 'Version')); + assert(is_a($b, 'Version')); + assert($a->isValid()); + assert($b->isValid()); + + if ($a->major != $b->major) { + return $a->major - $b->major; + } + + if ($a->minor != $b->minor) { + return $a->minor - $b->minor; + } + + if ($a->release != $b->release) { + return $a->release - $b->release; + } + + if ($a->build != $b->build) { + return $a->build - $b->build; + } + + return 0; + } + + /** + * Produce a string version + * + * @returns string the version encoded in FVF conformant string + */ + function toString() { + $chunks = array($this->major); + + if (isset($this->minor)) { + $chunks[] = $this->minor; + + if (isset($this->release)) { + $chunks[] = $this->release; + + if (isset($this->build)) { + + if (isset($this->plus)) { + $chunks[] = $this->build . $this->plus; + } else { + $chunks[] = $this->build; + } + } + } + } + + return implode('.', $chunks); + } +} +?> diff --git a/mozilla/webtools/addons/shared/sql/amo.sql b/mozilla/webtools/addons/shared/sql/amo.sql new file mode 100644 index 00000000000..6a41a0fb2df --- /dev/null +++ b/mozilla/webtools/addons/shared/sql/amo.sql @@ -0,0 +1,7 @@ + +CREATE TABLE PHPSESSION ( + SESSIONID VARCHAR(32) NOT NULL DEFAULT '', + SESSIONDATA TEXT NOT NULL DEFAULT '', + PRIMARY KEY(SESSIONID) +) +ENGINE=InnoDB;