/labs/tiles/12 | /labs/tiles/12 |
/labs/tiles/13 | /labs/tiles/13 |
/labs/tiles/14 | /labs/tiles/14 |
/labs/tiles/15 | /labs/tiles/15 |
/labs/tiles/16 | /labs/tiles/16 |
/labs/tiles/17 | /labs/tiles/17 |
/labs/tiles/19 | /labs/tiles/19 |
/nbproject/private/ |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
include ('include/common.inc.php'); | include ('include/common.inc.php'); |
include_header("About", "about") | include_header("About", "about") |
?> | ?> |
<p> | <p> |
Busness Time - An ACT bus timetable webapp<br /> | Busness Time - An ACT bus timetable webapp<br /> |
Based on the maxious-canberra-transit-feed (<a | Based on the maxious-canberra-transit-feed (<a |
href="http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip">download</a>, | href="http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip">download</a>, |
last updated <?php | last updated <?php echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> |
echo date("F d Y.", @filemtime('cbrfeed.zip')); ?>)<br /> | Source code for the <a |
Source code for the <a | href="https://github.com/maxious/ACTBus-data">transit |
href="https://github.com/maxious/ACTBus-data">transit | feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this |
feed</a> and <a href="https://github.com/maxious/ACTBus-ui">this | site</a> available from github.<br /> |
site</a> available from github.<br /> | Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br /> |
Uses jQuery Mobile, PHP, PostgreSQL, OpenTripPlanner, OpenLayers, OpenStreetMap, Cloudmade Geocoder and Tile Service<br /> | Suburb Geocoding Based on <A href="http://www.abs.gov.au/AUSSTATS/abs@.nsf/Lookup/1270.0.55.003Main+Features1July%202011?OpenDocument">Australian Bureau of Statistics data.</a><br /> |
<br /> | Street geocoding based on work by OpenStreetMap contributors<br> |
Feedback encouraged; contact maxious@lambdacomplex.org<br /> | |
<br /> | <br /> |
Some icons by Joseph Wain / glyphish.com<br /> | Feedback encouraged; contact maxious@lambdacomplex.org<br /> |
Native clients also available for iPhone(<a href="http://itunes.apple.com/au/app/cbrtimetable/id444287349?mt=8">cbrTimetable by Sandor Kolotenko</a> | <br /> |
, <a href="http://itunes.apple.com/au/app/act-buses/id376634797?mt=8">ACT Buses by David Sullivan</a>) | Some icons by Joseph Wain / glyphish.com<br /> |
and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>) | Native clients also available for iPhone(<a href="http://itunes.apple.com/au/app/cbrtimetable/id444287349?mt=8">cbrTimetable by Sandor Kolotenko</a> |
<br /> | , <a href="http://itunes.apple.com/au/app/act-buses/id376634797?mt=8">ACT Buses by David Sullivan</a>) |
<br /> | and Android (<a href="https://market.android.com/details?id=com.action">MyBus 2.0 by Imagine Team</a>) |
<small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. | <br /> |
Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, | GTFS-realtime API: |
express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided | Alerts and Trip Updates (but only Cancelled or Stop Skipped) |
"as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. | Default format binary Protocol Buffer but can get JSON by adding ?ascii=yes |
All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, | <br /> |
change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site | <br /> |
without prior notice. </small> | <small>Disclaimer: The content of this website is of a general and informative nature. Please check with printed timetables or those available on http://action.act.gov.au before your trip. |
<?php | Whilst every effort has been made to ensure the high quality and accuracy of the Site, the Author makes no warranty, |
include_footer(); | express or implied concerning the topicality, correctness, completeness or quality of the information, which is provided |
?> | "as is". The Author expressly disclaims all warranties, including but not limited to warranties of fitness for a particular purpose and warranties of merchantability. |
All offers are not binding and without obligation. The Author expressly reserves the right, in his discretion, to suspend, | |
change, modify, add or remove portions of the Site and to restrict or terminate the use and accessibility of the Site | |
without prior notice. </small> | |
<?php | |
include_footer(); | |
?> | |
cp /root/aws.php /tmp/ | cp /root/aws.php /tmp/ |
mkdir /var/www/lib/staticmaplite/cache | chmod 777 /var/cache/lighttpd/compress/ |
chcon -h system_u:object_r:httpd_sys_content_t /var/www | chcon -h system_u:object_r:httpd_sys_content_t /var/www |
chcon -R -h root:object_r:httpd_sys_content_t /var/www/* | chcon -R -h root:object_r:httpd_sys_content_t /var/www/* |
chcon -R -t httpd_sys_content_rw_t /var/www/lib/staticmaplite/cache | |
chmod -R 777 /var/www/lib/staticmaplite/cache | |
chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles | chcon -R -t httpd_sys_content_rw_t /var/www/labs/tiles |
chmod -R 777 /var/www/labs/tiles | chmod -R 777 /var/www/labs/tiles |
chcon -R -t httpd_sys_content_rw_t /var/www/lib/openid-php/oid_store | |
chmod -R 777 /var/www/lib/openid-php/oid_store | |
wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ | wget http://s3-ap-southeast-1.amazonaws.com/busresources/cbrfeed.zip \ |
-O /var/www/cbrfeed.zip | -O /var/www/cbrfeed.zip |
-- | |
-- PostgreSQL database dump | |
-- | |
-- Dumped from database version 9.0.4 | |
-- Dumped by pg_dump version 9.0.4 | |
-- Started on 2011-10-07 22:30:10 | |
SET statement_timeout = 0; | |
SET client_encoding = 'UTF8'; | |
SET standard_conforming_strings = off; | |
SET check_function_bodies = false; | |
SET client_min_messages = warning; | |
SET escape_string_warning = off; | |
-- | |
-- TOC entry 2772 (class 1262 OID 18349) | |
-- Name: transitdata; Type: DATABASE; Schema: -; Owner: postgres | |
-- | |
CREATE DATABASE transitdata WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'English_Australia.1252' LC_CTYPE = 'English_Australia.1252'; | |
ALTER DATABASE transitdata OWNER TO postgres; | |
\connect transitdata | |
SET statement_timeout = 0; | |
SET client_encoding = 'UTF8'; | |
SET standard_conforming_strings = off; | |
SET check_function_bodies = false; | |
SET client_min_messages = warning; | |
SET escape_string_warning = off; | |
-- | |
-- TOC entry 1170 (class 2612 OID 11574) | |
-- Name: plpgsql; Type: PROCEDURAL LANGUAGE; Schema: -; Owner: postgres | |
-- | |
CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql; | |
ALTER PROCEDURAL LANGUAGE plpgsql OWNER TO postgres; | |
SET search_path = public, pg_catalog; | |
-- | |
-- TOC entry 1088 (class 0 OID 0) | |
-- Name: box2d; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE box2d; | |
-- | |
-- TOC entry 15 (class 1255 OID 18351) | |
-- Dependencies: 6 1088 | |
-- Name: box2d_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box2d_in(cstring) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_in'; | |
ALTER FUNCTION public.box2d_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 19 (class 1255 OID 18352) | |
-- Dependencies: 6 1088 | |
-- Name: box2d_out(box2d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box2d_out(box2d) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_out'; | |
ALTER FUNCTION public.box2d_out(box2d) OWNER TO postgres; | |
-- | |
-- TOC entry 1087 (class 1247 OID 18350) | |
-- Dependencies: 15 6 19 | |
-- Name: box2d; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE box2d ( | |
INTERNALLENGTH = 16, | |
INPUT = box2d_in, | |
OUTPUT = box2d_out, | |
ALIGNMENT = int4, | |
STORAGE = plain | |
); | |
ALTER TYPE public.box2d OWNER TO postgres; | |
-- | |
-- TOC entry 1091 (class 0 OID 0) | |
-- Name: box3d; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE box3d; | |
-- | |
-- TOC entry 20 (class 1255 OID 18355) | |
-- Dependencies: 6 1091 | |
-- Name: box3d_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d_in(cstring) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_in'; | |
ALTER FUNCTION public.box3d_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 21 (class 1255 OID 18356) | |
-- Dependencies: 6 1091 | |
-- Name: box3d_out(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d_out(box3d) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_out'; | |
ALTER FUNCTION public.box3d_out(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 1090 (class 1247 OID 18354) | |
-- Dependencies: 21 6 20 | |
-- Name: box3d; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE box3d ( | |
INTERNALLENGTH = 48, | |
INPUT = box3d_in, | |
OUTPUT = box3d_out, | |
ALIGNMENT = double, | |
STORAGE = plain | |
); | |
ALTER TYPE public.box3d OWNER TO postgres; | |
-- | |
-- TOC entry 1094 (class 0 OID 0) | |
-- Name: box3d_extent; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE box3d_extent; | |
-- | |
-- TOC entry 22 (class 1255 OID 18359) | |
-- Dependencies: 6 1094 | |
-- Name: box3d_extent_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d_extent_in(cstring) RETURNS box3d_extent | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_in'; | |
ALTER FUNCTION public.box3d_extent_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 23 (class 1255 OID 18360) | |
-- Dependencies: 6 1094 | |
-- Name: box3d_extent_out(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d_extent_out(box3d_extent) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_extent_out'; | |
ALTER FUNCTION public.box3d_extent_out(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 1093 (class 1247 OID 18358) | |
-- Dependencies: 6 22 23 | |
-- Name: box3d_extent; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE box3d_extent ( | |
INTERNALLENGTH = 48, | |
INPUT = box3d_extent_in, | |
OUTPUT = box3d_extent_out, | |
ALIGNMENT = double, | |
STORAGE = plain | |
); | |
ALTER TYPE public.box3d_extent OWNER TO postgres; | |
-- | |
-- TOC entry 1097 (class 0 OID 0) | |
-- Name: chip; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE chip; | |
-- | |
-- TOC entry 24 (class 1255 OID 18363) | |
-- Dependencies: 6 1097 | |
-- Name: chip_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION chip_in(cstring) RETURNS chip | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_in'; | |
ALTER FUNCTION public.chip_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 25 (class 1255 OID 18364) | |
-- Dependencies: 6 1097 | |
-- Name: chip_out(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION chip_out(chip) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_out'; | |
ALTER FUNCTION public.chip_out(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 1096 (class 1247 OID 18362) | |
-- Dependencies: 6 25 24 | |
-- Name: chip; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE chip ( | |
INTERNALLENGTH = variable, | |
INPUT = chip_in, | |
OUTPUT = chip_out, | |
ALIGNMENT = double, | |
STORAGE = extended | |
); | |
ALTER TYPE public.chip OWNER TO postgres; | |
-- | |
-- TOC entry 1100 (class 0 OID 0) | |
-- Name: geography; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE geography; | |
-- | |
-- TOC entry 26 (class 1255 OID 18367) | |
-- Dependencies: 6 | |
-- Name: geography_analyze(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_analyze(internal) RETURNS boolean | |
LANGUAGE c STRICT | |
AS '$libdir/postgis-1.5', 'geography_analyze'; | |
ALTER FUNCTION public.geography_analyze(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 27 (class 1255 OID 18368) | |
-- Dependencies: 6 1100 | |
-- Name: geography_in(cstring, oid, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_in(cstring, oid, integer) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_in'; | |
ALTER FUNCTION public.geography_in(cstring, oid, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 28 (class 1255 OID 18369) | |
-- Dependencies: 6 1100 | |
-- Name: geography_out(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_out(geography) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_out'; | |
ALTER FUNCTION public.geography_out(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 29 (class 1255 OID 18370) | |
-- Dependencies: 6 | |
-- Name: geography_typmod_in(cstring[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_typmod_in(cstring[]) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_typmod_in'; | |
ALTER FUNCTION public.geography_typmod_in(cstring[]) OWNER TO postgres; | |
-- | |
-- TOC entry 30 (class 1255 OID 18371) | |
-- Dependencies: 6 | |
-- Name: geography_typmod_out(integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_typmod_out(integer) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_typmod_out'; | |
ALTER FUNCTION public.geography_typmod_out(integer) OWNER TO postgres; | |
-- | |
-- TOC entry 1099 (class 1247 OID 18366) | |
-- Dependencies: 29 30 26 6 27 28 | |
-- Name: geography; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE geography ( | |
INTERNALLENGTH = variable, | |
INPUT = geography_in, | |
OUTPUT = geography_out, | |
TYPMOD_IN = geography_typmod_in, | |
TYPMOD_OUT = geography_typmod_out, | |
ANALYZE = geography_analyze, | |
ALIGNMENT = double, | |
STORAGE = main | |
); | |
ALTER TYPE public.geography OWNER TO postgres; | |
-- | |
-- TOC entry 1103 (class 0 OID 0) | |
-- Name: geometry; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE geometry; | |
-- | |
-- TOC entry 31 (class 1255 OID 18374) | |
-- Dependencies: 6 | |
-- Name: geometry_analyze(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_analyze(internal) RETURNS boolean | |
LANGUAGE c STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_analyze'; | |
ALTER FUNCTION public.geometry_analyze(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 32 (class 1255 OID 18375) | |
-- Dependencies: 6 1103 | |
-- Name: geometry_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_in(cstring) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_in'; | |
ALTER FUNCTION public.geometry_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 33 (class 1255 OID 18376) | |
-- Dependencies: 6 1103 | |
-- Name: geometry_out(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_out(geometry) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_out'; | |
ALTER FUNCTION public.geometry_out(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 34 (class 1255 OID 18377) | |
-- Dependencies: 6 1103 | |
-- Name: geometry_recv(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_recv(internal) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_recv'; | |
ALTER FUNCTION public.geometry_recv(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 35 (class 1255 OID 18378) | |
-- Dependencies: 6 1103 | |
-- Name: geometry_send(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_send(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_send'; | |
ALTER FUNCTION public.geometry_send(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1102 (class 1247 OID 18373) | |
-- Dependencies: 35 31 32 6 33 34 | |
-- Name: geometry; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE geometry ( | |
INTERNALLENGTH = variable, | |
INPUT = geometry_in, | |
OUTPUT = geometry_out, | |
RECEIVE = geometry_recv, | |
SEND = geometry_send, | |
ANALYZE = geometry_analyze, | |
DELIMITER = ':', | |
ALIGNMENT = int4, | |
STORAGE = main | |
); | |
ALTER TYPE public.geometry OWNER TO postgres; | |
-- | |
-- TOC entry 1105 (class 1247 OID 18382) | |
-- Dependencies: 6 2410 | |
-- Name: geometry_dump; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE geometry_dump AS ( | |
path integer[], | |
geom geometry | |
); | |
ALTER TYPE public.geometry_dump OWNER TO postgres; | |
-- | |
-- TOC entry 1108 (class 0 OID 0) | |
-- Name: gidx; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE gidx; | |
-- | |
-- TOC entry 36 (class 1255 OID 18384) | |
-- Dependencies: 6 1108 | |
-- Name: gidx_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION gidx_in(cstring) RETURNS gidx | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'gidx_in'; | |
ALTER FUNCTION public.gidx_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 37 (class 1255 OID 18385) | |
-- Dependencies: 6 1108 | |
-- Name: gidx_out(gidx); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION gidx_out(gidx) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'gidx_out'; | |
ALTER FUNCTION public.gidx_out(gidx) OWNER TO postgres; | |
-- | |
-- TOC entry 1107 (class 1247 OID 18383) | |
-- Dependencies: 36 6 37 | |
-- Name: gidx; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE gidx ( | |
INTERNALLENGTH = variable, | |
INPUT = gidx_in, | |
OUTPUT = gidx_out, | |
ALIGNMENT = double, | |
STORAGE = plain | |
); | |
ALTER TYPE public.gidx OWNER TO postgres; | |
-- | |
-- TOC entry 1111 (class 0 OID 0) | |
-- Name: pgis_abs; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE pgis_abs; | |
-- | |
-- TOC entry 38 (class 1255 OID 18388) | |
-- Dependencies: 6 1111 | |
-- Name: pgis_abs_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_abs_in(cstring) RETURNS pgis_abs | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'pgis_abs_in'; | |
ALTER FUNCTION public.pgis_abs_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 39 (class 1255 OID 18389) | |
-- Dependencies: 6 1111 | |
-- Name: pgis_abs_out(pgis_abs); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_abs_out(pgis_abs) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'pgis_abs_out'; | |
ALTER FUNCTION public.pgis_abs_out(pgis_abs) OWNER TO postgres; | |
-- | |
-- TOC entry 1110 (class 1247 OID 18387) | |
-- Dependencies: 39 6 38 | |
-- Name: pgis_abs; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE pgis_abs ( | |
INTERNALLENGTH = 8, | |
INPUT = pgis_abs_in, | |
OUTPUT = pgis_abs_out, | |
ALIGNMENT = double, | |
STORAGE = plain | |
); | |
ALTER TYPE public.pgis_abs OWNER TO postgres; | |
-- | |
-- TOC entry 1114 (class 0 OID 0) | |
-- Name: spheroid; Type: SHELL TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE spheroid; | |
-- | |
-- TOC entry 40 (class 1255 OID 18392) | |
-- Dependencies: 6 1114 | |
-- Name: spheroid_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION spheroid_in(cstring) RETURNS spheroid | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ellipsoid_in'; | |
ALTER FUNCTION public.spheroid_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 41 (class 1255 OID 18393) | |
-- Dependencies: 6 1114 | |
-- Name: spheroid_out(spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION spheroid_out(spheroid) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ellipsoid_out'; | |
ALTER FUNCTION public.spheroid_out(spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 1113 (class 1247 OID 18391) | |
-- Dependencies: 6 41 40 | |
-- Name: spheroid; Type: TYPE; Schema: public; Owner: postgres | |
-- | |
CREATE TYPE spheroid ( | |
INTERNALLENGTH = 65, | |
INPUT = spheroid_in, | |
OUTPUT = spheroid_out, | |
ALIGNMENT = double, | |
STORAGE = plain | |
); | |
ALTER TYPE public.spheroid OWNER TO postgres; | |
-- | |
-- TOC entry 42 (class 1255 OID 18395) | |
-- Dependencies: 6 1102 | |
-- Name: _st_asgeojson(integer, geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_asgeojson(integer, geometry, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asGeoJson'; | |
ALTER FUNCTION public._st_asgeojson(integer, geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 43 (class 1255 OID 18396) | |
-- Dependencies: 1099 6 | |
-- Name: _st_asgeojson(integer, geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_asgeojson(integer, geography, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_geojson'; | |
ALTER FUNCTION public._st_asgeojson(integer, geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 44 (class 1255 OID 18397) | |
-- Dependencies: 1102 6 | |
-- Name: _st_asgml(integer, geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_asgml(integer, geometry, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asGML'; | |
ALTER FUNCTION public._st_asgml(integer, geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 45 (class 1255 OID 18398) | |
-- Dependencies: 1099 6 | |
-- Name: _st_asgml(integer, geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_asgml(integer, geography, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_gml'; | |
ALTER FUNCTION public._st_asgml(integer, geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 46 (class 1255 OID 18399) | |
-- Dependencies: 6 1102 | |
-- Name: _st_askml(integer, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_askml(integer, geometry, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asKML'; | |
ALTER FUNCTION public._st_askml(integer, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 47 (class 1255 OID 18400) | |
-- Dependencies: 1099 6 | |
-- Name: _st_askml(integer, geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_askml(integer, geography, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_kml'; | |
ALTER FUNCTION public._st_askml(integer, geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 49 (class 1255 OID 18402) | |
-- Dependencies: 6 1099 | |
-- Name: _st_bestsrid(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_bestsrid(geography) RETURNS integer | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_BestSRID($1,$1)$_$; | |
ALTER FUNCTION public._st_bestsrid(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 48 (class 1255 OID 18401) | |
-- Dependencies: 1099 6 1099 | |
-- Name: _st_bestsrid(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_bestsrid(geography, geography) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_bestsrid'; | |
ALTER FUNCTION public._st_bestsrid(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 50 (class 1255 OID 18403) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_buffer(geometry, double precision, cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_buffer(geometry, double precision, cstring) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'buffer'; | |
ALTER FUNCTION public._st_buffer(geometry, double precision, cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 51 (class 1255 OID 18404) | |
-- Dependencies: 6 1102 1102 | |
-- Name: _st_contains(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_contains(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'contains'; | |
ALTER FUNCTION public._st_contains(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 52 (class 1255 OID 18405) | |
-- Dependencies: 6 1102 1102 | |
-- Name: _st_containsproperly(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_containsproperly(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'containsproperly'; | |
ALTER FUNCTION public._st_containsproperly(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 53 (class 1255 OID 18406) | |
-- Dependencies: 6 1102 1102 | |
-- Name: _st_coveredby(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_coveredby(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'coveredby'; | |
ALTER FUNCTION public._st_coveredby(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 54 (class 1255 OID 18407) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_covers(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_covers(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'covers'; | |
ALTER FUNCTION public._st_covers(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 55 (class 1255 OID 18408) | |
-- Dependencies: 1099 6 1099 | |
-- Name: _st_covers(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_covers(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'geography_covers'; | |
ALTER FUNCTION public._st_covers(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 56 (class 1255 OID 18409) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_crosses(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_crosses(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'crosses'; | |
ALTER FUNCTION public._st_crosses(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 57 (class 1255 OID 18410) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_dfullywithin(geometry, geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_dfullywithin(geometry, geometry, double precision) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dfullywithin'; | |
ALTER FUNCTION public._st_dfullywithin(geometry, geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 58 (class 1255 OID 18411) | |
-- Dependencies: 1099 1099 6 | |
-- Name: _st_distance(geography, geography, double precision, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_distance(geography, geography, double precision, boolean) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'geography_distance'; | |
ALTER FUNCTION public._st_distance(geography, geography, double precision, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 59 (class 1255 OID 18412) | |
-- Dependencies: 1105 1170 6 1102 | |
-- Name: _st_dumppoints(geometry, integer[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_dumppoints(the_geom geometry, cur_path integer[]) RETURNS SETOF geometry_dump | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
tmp geometry_dump; | |
tmp2 geometry_dump; | |
nb_points integer; | |
nb_geom integer; | |
i integer; | |
j integer; | |
g geometry; | |
BEGIN | |
RAISE DEBUG '%,%', cur_path, ST_GeometryType(the_geom); | |
-- Special case (MULTI* OR GEOMETRYCOLLECTION) : iterate and return the DumpPoints of the geometries | |
SELECT ST_NumGeometries(the_geom) INTO nb_geom; | |
IF (nb_geom IS NOT NULL) THEN | |
i = 1; | |
FOR tmp2 IN SELECT (ST_Dump(the_geom)).* LOOP | |
FOR tmp IN SELECT * FROM _ST_DumpPoints(tmp2.geom, cur_path || tmp2.path) LOOP | |
RETURN NEXT tmp; | |
END LOOP; | |
i = i + 1; | |
END LOOP; | |
RETURN; | |
END IF; | |
-- Special case (POLYGON) : return the points of the rings of a polygon | |
IF (ST_GeometryType(the_geom) = 'ST_Polygon') THEN | |
FOR tmp IN SELECT * FROM _ST_DumpPoints(ST_ExteriorRing(the_geom), cur_path || ARRAY[1]) LOOP | |
RETURN NEXT tmp; | |
END LOOP; | |
j := ST_NumInteriorRings(the_geom); | |
FOR i IN 1..j LOOP | |
FOR tmp IN SELECT * FROM _ST_DumpPoints(ST_InteriorRingN(the_geom, i), cur_path || ARRAY[i+1]) LOOP | |
RETURN NEXT tmp; | |
END LOOP; | |
END LOOP; | |
RETURN; | |
END IF; | |
-- Special case (POINT) : return the point | |
IF (ST_GeometryType(the_geom) = 'ST_Point') THEN | |
tmp.path = cur_path || ARRAY[1]; | |
tmp.geom = the_geom; | |
RETURN NEXT tmp; | |
RETURN; | |
END IF; | |
-- Use ST_NumPoints rather than ST_NPoints to have a NULL value if the_geom isn't | |
-- a LINESTRING or CIRCULARSTRING. | |
SELECT ST_NumPoints(the_geom) INTO nb_points; | |
-- This should never happen | |
IF (nb_points IS NULL) THEN | |
RAISE EXCEPTION 'Unexpected error while dumping geometry %', ST_AsText(the_geom); | |
END IF; | |
FOR i IN 1..nb_points LOOP | |
tmp.path = cur_path || ARRAY[i]; | |
tmp.geom := ST_PointN(the_geom, i); | |
RETURN NEXT tmp; | |
END LOOP; | |
END | |
$$; | |
ALTER FUNCTION public._st_dumppoints(the_geom geometry, cur_path integer[]) OWNER TO postgres; | |
-- | |
-- TOC entry 60 (class 1255 OID 18413) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_dwithin(geometry, geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_dwithin(geometry, geometry, double precision) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_dwithin'; | |
ALTER FUNCTION public._st_dwithin(geometry, geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 61 (class 1255 OID 18414) | |
-- Dependencies: 1099 6 1099 | |
-- Name: _st_dwithin(geography, geography, double precision, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_dwithin(geography, geography, double precision, boolean) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'geography_dwithin'; | |
ALTER FUNCTION public._st_dwithin(geography, geography, double precision, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 62 (class 1255 OID 18415) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_equals(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_equals(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'geomequals'; | |
ALTER FUNCTION public._st_equals(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 63 (class 1255 OID 18416) | |
-- Dependencies: 1099 6 1099 | |
-- Name: _st_expand(geography, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_expand(geography, double precision) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_expand'; | |
ALTER FUNCTION public._st_expand(geography, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 64 (class 1255 OID 18417) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_intersects(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_intersects(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'intersects'; | |
ALTER FUNCTION public._st_intersects(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 65 (class 1255 OID 18418) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_linecrossingdirection(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_linecrossingdirection(geometry, geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'ST_LineCrossingDirection'; | |
ALTER FUNCTION public._st_linecrossingdirection(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 66 (class 1255 OID 18419) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: _st_longestline(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_longestline(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_longestline2d'; | |
ALTER FUNCTION public._st_longestline(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 67 (class 1255 OID 18420) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_maxdistance(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_maxdistance(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_maxdistance2d_linestring'; | |
ALTER FUNCTION public._st_maxdistance(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 68 (class 1255 OID 18421) | |
-- Dependencies: 6 1102 1102 | |
-- Name: _st_orderingequals(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_orderingequals(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_same'; | |
ALTER FUNCTION public._st_orderingequals(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 69 (class 1255 OID 18422) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_overlaps(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_overlaps(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'overlaps'; | |
ALTER FUNCTION public._st_overlaps(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 70 (class 1255 OID 18423) | |
-- Dependencies: 1099 6 1099 | |
-- Name: _st_pointoutside(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_pointoutside(geography) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_point_outside'; | |
ALTER FUNCTION public._st_pointoutside(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 71 (class 1255 OID 18424) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_touches(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_touches(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'touches'; | |
ALTER FUNCTION public._st_touches(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 72 (class 1255 OID 18425) | |
-- Dependencies: 1102 6 1102 | |
-- Name: _st_within(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION _st_within(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'within'; | |
ALTER FUNCTION public._st_within(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 73 (class 1255 OID 18426) | |
-- Dependencies: 6 1170 | |
-- Name: addauth(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addauth(text) RETURNS boolean | |
LANGUAGE plpgsql | |
AS $_$ | |
DECLARE | |
lockid alias for $1; | |
okay boolean; | |
myrec record; | |
BEGIN | |
-- check to see if table exists | |
-- if not, CREATE TEMP TABLE mylock (transid xid, lockcode text) | |
okay := 'f'; | |
FOR myrec IN SELECT * FROM pg_class WHERE relname = 'temp_lock_have_table' LOOP | |
okay := 't'; | |
END LOOP; | |
IF (okay <> 't') THEN | |
CREATE TEMP TABLE temp_lock_have_table (transid xid, lockcode text); | |
-- this will only work from pgsql7.4 up | |
-- ON COMMIT DELETE ROWS; | |
END IF; | |
-- INSERT INTO mylock VALUES ( $1) | |
-- EXECUTE 'INSERT INTO temp_lock_have_table VALUES ( '|| | |
-- quote_literal(getTransactionID()) || ',' || | |
-- quote_literal(lockid) ||')'; | |
INSERT INTO temp_lock_have_table VALUES (getTransactionID(), lockid); | |
RETURN true::boolean; | |
END; | |
$_$; | |
ALTER FUNCTION public.addauth(text) OWNER TO postgres; | |
-- | |
-- TOC entry 74 (class 1255 OID 18427) | |
-- Dependencies: 1102 6 1102 | |
-- Name: addbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addbbox(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_addBBOX'; | |
ALTER FUNCTION public.addbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 79 (class 1255 OID 18430) | |
-- Dependencies: 6 1170 | |
-- Name: addgeometrycolumn(character varying, character varying, integer, character varying, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addgeometrycolumn(character varying, character varying, integer, character varying, integer) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
ret text; | |
BEGIN | |
SELECT AddGeometryColumn('','',$1,$2,$3,$4,$5) into ret; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.addgeometrycolumn(character varying, character varying, integer, character varying, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 78 (class 1255 OID 18429) | |
-- Dependencies: 6 1170 | |
-- Name: addgeometrycolumn(character varying, character varying, character varying, integer, character varying, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addgeometrycolumn(character varying, character varying, character varying, integer, character varying, integer) RETURNS text | |
LANGUAGE plpgsql STABLE STRICT | |
AS $_$ | |
DECLARE | |
ret text; | |
BEGIN | |
SELECT AddGeometryColumn('',$1,$2,$3,$4,$5,$6) into ret; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.addgeometrycolumn(character varying, character varying, character varying, integer, character varying, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 77 (class 1255 OID 18428) | |
-- Dependencies: 6 1170 | |
-- Name: addgeometrycolumn(character varying, character varying, character varying, character varying, integer, character varying, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addgeometrycolumn(character varying, character varying, character varying, character varying, integer, character varying, integer) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
catalog_name alias for $1; | |
schema_name alias for $2; | |
table_name alias for $3; | |
column_name alias for $4; | |
new_srid alias for $5; | |
new_type alias for $6; | |
new_dim alias for $7; | |
rec RECORD; | |
sr varchar; | |
real_schema name; | |
sql text; | |
BEGIN | |
-- Verify geometry type | |
IF ( NOT ( (new_type = 'GEOMETRY') OR | |
(new_type = 'GEOMETRYCOLLECTION') OR | |
(new_type = 'POINT') OR | |
(new_type = 'MULTIPOINT') OR | |
(new_type = 'POLYGON') OR | |
(new_type = 'MULTIPOLYGON') OR | |
(new_type = 'LINESTRING') OR | |
(new_type = 'MULTILINESTRING') OR | |
(new_type = 'GEOMETRYCOLLECTIONM') OR | |
(new_type = 'POINTM') OR | |
(new_type = 'MULTIPOINTM') OR | |
(new_type = 'POLYGONM') OR | |
(new_type = 'MULTIPOLYGONM') OR | |
(new_type = 'LINESTRINGM') OR | |
(new_type = 'MULTILINESTRINGM') OR | |
(new_type = 'CIRCULARSTRING') OR | |
(new_type = 'CIRCULARSTRINGM') OR | |
(new_type = 'COMPOUNDCURVE') OR | |
(new_type = 'COMPOUNDCURVEM') OR | |
(new_type = 'CURVEPOLYGON') OR | |
(new_type = 'CURVEPOLYGONM') OR | |
(new_type = 'MULTICURVE') OR | |
(new_type = 'MULTICURVEM') OR | |
(new_type = 'MULTISURFACE') OR | |
(new_type = 'MULTISURFACEM')) ) | |
THEN | |
RAISE EXCEPTION 'Invalid type name - valid ones are: | |
POINT, MULTIPOINT, | |
LINESTRING, MULTILINESTRING, | |
POLYGON, MULTIPOLYGON, | |
CIRCULARSTRING, COMPOUNDCURVE, MULTICURVE, | |
CURVEPOLYGON, MULTISURFACE, | |
GEOMETRY, GEOMETRYCOLLECTION, | |
POINTM, MULTIPOINTM, | |
LINESTRINGM, MULTILINESTRINGM, | |
POLYGONM, MULTIPOLYGONM, | |
CIRCULARSTRINGM, COMPOUNDCURVEM, MULTICURVEM | |
CURVEPOLYGONM, MULTISURFACEM, | |
or GEOMETRYCOLLECTIONM'; | |
RETURN 'fail'; | |
END IF; | |
-- Verify dimension | |
IF ( (new_dim >4) OR (new_dim <0) ) THEN | |
RAISE EXCEPTION 'invalid dimension'; | |
RETURN 'fail'; | |
END IF; | |
IF ( (new_type LIKE '%M') AND (new_dim!=3) ) THEN | |
RAISE EXCEPTION 'TypeM needs 3 dimensions'; | |
RETURN 'fail'; | |
END IF; | |
-- Verify SRID | |
IF ( new_srid != -1 ) THEN | |
SELECT SRID INTO sr FROM spatial_ref_sys WHERE SRID = new_srid; | |
IF NOT FOUND THEN | |
RAISE EXCEPTION 'AddGeometryColumns() - invalid SRID'; | |
RETURN 'fail'; | |
END IF; | |
END IF; | |
-- Verify schema | |
IF ( schema_name IS NOT NULL AND schema_name != '' ) THEN | |
sql := 'SELECT nspname FROM pg_namespace ' || | |
'WHERE text(nspname) = ' || quote_literal(schema_name) || | |
'LIMIT 1'; | |
RAISE DEBUG '%', sql; | |
EXECUTE sql INTO real_schema; | |
IF ( real_schema IS NULL ) THEN | |
RAISE EXCEPTION 'Schema % is not a valid schemaname', quote_literal(schema_name); | |
RETURN 'fail'; | |
END IF; | |
END IF; | |
IF ( real_schema IS NULL ) THEN | |
RAISE DEBUG 'Detecting schema'; | |
sql := 'SELECT n.nspname AS schemaname ' || | |
'FROM pg_catalog.pg_class c ' || | |
'JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace ' || | |
'WHERE c.relkind = ' || quote_literal('r') || | |
' AND n.nspname NOT IN (' || quote_literal('pg_catalog') || ', ' || quote_literal('pg_toast') || ')' || | |
' AND pg_catalog.pg_table_is_visible(c.oid)' || | |
' AND c.relname = ' || quote_literal(table_name); | |
RAISE DEBUG '%', sql; | |
EXECUTE sql INTO real_schema; | |
IF ( real_schema IS NULL ) THEN | |
RAISE EXCEPTION 'Table % does not occur in the search_path', quote_literal(table_name); | |
RETURN 'fail'; | |
END IF; | |
END IF; | |
-- Add geometry column to table | |
sql := 'ALTER TABLE ' || | |
quote_ident(real_schema) || '.' || quote_ident(table_name) | |
|| ' ADD COLUMN ' || quote_ident(column_name) || | |
' geometry '; | |
RAISE DEBUG '%', sql; | |
EXECUTE sql; | |
-- Delete stale record in geometry_columns (if any) | |
sql := 'DELETE FROM geometry_columns WHERE | |
f_table_catalog = ' || quote_literal('') || | |
' AND f_table_schema = ' || | |
quote_literal(real_schema) || | |
' AND f_table_name = ' || quote_literal(table_name) || | |
' AND f_geometry_column = ' || quote_literal(column_name); | |
RAISE DEBUG '%', sql; | |
EXECUTE sql; | |
-- Add record in geometry_columns | |
sql := 'INSERT INTO geometry_columns (f_table_catalog,f_table_schema,f_table_name,' || | |
'f_geometry_column,coord_dimension,srid,type)' || | |
' VALUES (' || | |
quote_literal('') || ',' || | |
quote_literal(real_schema) || ',' || | |
quote_literal(table_name) || ',' || | |
quote_literal(column_name) || ',' || | |
new_dim::text || ',' || | |
new_srid::text || ',' || | |
quote_literal(new_type) || ')'; | |
RAISE DEBUG '%', sql; | |
EXECUTE sql; | |
-- Add table CHECKs | |
sql := 'ALTER TABLE ' || | |
quote_ident(real_schema) || '.' || quote_ident(table_name) | |
|| ' ADD CONSTRAINT ' | |
|| quote_ident('enforce_srid_' || column_name) | |
|| ' CHECK (ST_SRID(' || quote_ident(column_name) || | |
') = ' || new_srid::text || ')' ; | |
RAISE DEBUG '%', sql; | |
EXECUTE sql; | |
sql := 'ALTER TABLE ' || | |
quote_ident(real_schema) || '.' || quote_ident(table_name) | |
|| ' ADD CONSTRAINT ' | |
|| quote_ident('enforce_dims_' || column_name) | |
|| ' CHECK (ST_NDims(' || quote_ident(column_name) || | |
') = ' || new_dim::text || ')' ; | |
RAISE DEBUG '%', sql; | |
EXECUTE sql; | |
IF ( NOT (new_type = 'GEOMETRY')) THEN | |
sql := 'ALTER TABLE ' || | |
quote_ident(real_schema) || '.' || quote_ident(table_name) || ' ADD CONSTRAINT ' || | |
quote_ident('enforce_geotype_' || column_name) || | |
' CHECK (GeometryType(' || | |
quote_ident(column_name) || ')=' || | |
quote_literal(new_type) || ' OR (' || | |
quote_ident(column_name) || ') is null)'; | |
RAISE DEBUG '%', sql; | |
EXECUTE sql; | |
END IF; | |
RETURN | |
real_schema || '.' || | |
table_name || '.' || column_name || | |
' SRID:' || new_srid::text || | |
' TYPE:' || new_type || | |
' DIMS:' || new_dim::text || ' '; | |
END; | |
$_$; | |
ALTER FUNCTION public.addgeometrycolumn(character varying, character varying, character varying, character varying, integer, character varying, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 80 (class 1255 OID 18431) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: addpoint(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addpoint(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_addpoint'; | |
ALTER FUNCTION public.addpoint(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 81 (class 1255 OID 18432) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: addpoint(geometry, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION addpoint(geometry, geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_addpoint'; | |
ALTER FUNCTION public.addpoint(geometry, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 83 (class 1255 OID 18434) | |
-- Dependencies: 1102 6 1102 | |
-- Name: affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, $2, $3, 0, $4, $5, 0, 0, 0, 1, $6, $7, 0)$_$; | |
ALTER FUNCTION public.affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 82 (class 1255 OID 18433) | |
-- Dependencies: 6 1102 1102 | |
-- Name: affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_affine'; | |
ALTER FUNCTION public.affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 84 (class 1255 OID 18435) | |
-- Dependencies: 6 1102 | |
-- Name: area(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION area(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_area_polygon'; | |
ALTER FUNCTION public.area(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 85 (class 1255 OID 18436) | |
-- Dependencies: 6 1102 | |
-- Name: area2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION area2d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_area_polygon'; | |
ALTER FUNCTION public.area2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 86 (class 1255 OID 18437) | |
-- Dependencies: 1102 6 | |
-- Name: asbinary(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asbinary(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asBinary'; | |
ALTER FUNCTION public.asbinary(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 87 (class 1255 OID 18438) | |
-- Dependencies: 6 1102 | |
-- Name: asbinary(geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asbinary(geometry, text) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asBinary'; | |
ALTER FUNCTION public.asbinary(geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 88 (class 1255 OID 18439) | |
-- Dependencies: 1102 6 | |
-- Name: asewkb(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asewkb(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'WKBFromLWGEOM'; | |
ALTER FUNCTION public.asewkb(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 89 (class 1255 OID 18440) | |
-- Dependencies: 6 1102 | |
-- Name: asewkb(geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asewkb(geometry, text) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'WKBFromLWGEOM'; | |
ALTER FUNCTION public.asewkb(geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 90 (class 1255 OID 18441) | |
-- Dependencies: 1102 6 | |
-- Name: asewkt(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asewkt(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asEWKT'; | |
ALTER FUNCTION public.asewkt(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 92 (class 1255 OID 18443) | |
-- Dependencies: 6 1102 | |
-- Name: asgml(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asgml(geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, 15, 0)$_$; | |
ALTER FUNCTION public.asgml(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 91 (class 1255 OID 18442) | |
-- Dependencies: 1102 6 | |
-- Name: asgml(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION asgml(geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, $2, 0)$_$; | |
ALTER FUNCTION public.asgml(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 93 (class 1255 OID 18444) | |
-- Dependencies: 1102 6 | |
-- Name: ashexewkb(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION ashexewkb(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asHEXEWKB'; | |
ALTER FUNCTION public.ashexewkb(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 94 (class 1255 OID 18445) | |
-- Dependencies: 6 1102 | |
-- Name: ashexewkb(geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION ashexewkb(geometry, text) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asHEXEWKB'; | |
ALTER FUNCTION public.ashexewkb(geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 96 (class 1255 OID 18447) | |
-- Dependencies: 6 1102 | |
-- Name: askml(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION askml(geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML(2, transform($1,4326), 15)$_$; | |
ALTER FUNCTION public.askml(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 95 (class 1255 OID 18446) | |
-- Dependencies: 6 1102 | |
-- Name: askml(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION askml(geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML(2, transform($1,4326), $2)$_$; | |
ALTER FUNCTION public.askml(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 97 (class 1255 OID 18448) | |
-- Dependencies: 1102 6 | |
-- Name: askml(integer, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION askml(integer, geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML($1, transform($2,4326), $3)$_$; | |
ALTER FUNCTION public.askml(integer, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 100 (class 1255 OID 18451) | |
-- Dependencies: 1102 6 | |
-- Name: assvg(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION assvg(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'assvg_geometry'; | |
ALTER FUNCTION public.assvg(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 99 (class 1255 OID 18450) | |
-- Dependencies: 6 1102 | |
-- Name: assvg(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION assvg(geometry, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'assvg_geometry'; | |
ALTER FUNCTION public.assvg(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 98 (class 1255 OID 18449) | |
-- Dependencies: 6 1102 | |
-- Name: assvg(geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION assvg(geometry, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'assvg_geometry'; | |
ALTER FUNCTION public.assvg(geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 101 (class 1255 OID 18452) | |
-- Dependencies: 6 1102 | |
-- Name: astext(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION astext(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asText'; | |
ALTER FUNCTION public.astext(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 102 (class 1255 OID 18453) | |
-- Dependencies: 6 1102 1102 | |
-- Name: azimuth(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION azimuth(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_azimuth'; | |
ALTER FUNCTION public.azimuth(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 103 (class 1255 OID 18454) | |
-- Dependencies: 1170 1102 6 | |
-- Name: bdmpolyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION bdmpolyfromtext(text, integer) RETURNS geometry | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
geomtext alias for $1; | |
srid alias for $2; | |
mline geometry; | |
geom geometry; | |
BEGIN | |
mline := MultiLineStringFromText(geomtext, srid); | |
IF mline IS NULL | |
THEN | |
RAISE EXCEPTION 'Input is not a MultiLinestring'; | |
END IF; | |
geom := multi(BuildArea(mline)); | |
RETURN geom; | |
END; | |
$_$; | |
ALTER FUNCTION public.bdmpolyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 75 (class 1255 OID 18455) | |
-- Dependencies: 1170 1102 6 | |
-- Name: bdpolyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION bdpolyfromtext(text, integer) RETURNS geometry | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
geomtext alias for $1; | |
srid alias for $2; | |
mline geometry; | |
geom geometry; | |
BEGIN | |
mline := MultiLineStringFromText(geomtext, srid); | |
IF mline IS NULL | |
THEN | |
RAISE EXCEPTION 'Input is not a MultiLinestring'; | |
END IF; | |
geom := BuildArea(mline); | |
IF GeometryType(geom) != 'POLYGON' | |
THEN | |
RAISE EXCEPTION 'Input returns more then a single polygon, try using BdMPolyFromText instead'; | |
END IF; | |
RETURN geom; | |
END; | |
$_$; | |
ALTER FUNCTION public.bdpolyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 76 (class 1255 OID 18456) | |
-- Dependencies: 1102 6 1102 | |
-- Name: boundary(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION boundary(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'boundary'; | |
ALTER FUNCTION public.boundary(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 104 (class 1255 OID 18457) | |
-- Dependencies: 1102 6 | |
-- Name: box(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box(geometry) RETURNS box | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX'; | |
ALTER FUNCTION public.box(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 105 (class 1255 OID 18458) | |
-- Dependencies: 1090 6 | |
-- Name: box(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box(box3d) RETURNS box | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_BOX'; | |
ALTER FUNCTION public.box(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 106 (class 1255 OID 18459) | |
-- Dependencies: 1093 1087 6 | |
-- Name: box2d(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box2d(box3d_extent) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.box2d(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 107 (class 1255 OID 18460) | |
-- Dependencies: 1102 1087 6 | |
-- Name: box2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box2d(geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.box2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 108 (class 1255 OID 18461) | |
-- Dependencies: 1087 1090 6 | |
-- Name: box2d(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box2d(box3d) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.box2d(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 109 (class 1255 OID 18462) | |
-- Dependencies: 6 1090 1102 | |
-- Name: box3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d(geometry) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX3D'; | |
ALTER FUNCTION public.box3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 110 (class 1255 OID 18463) | |
-- Dependencies: 1087 6 1090 | |
-- Name: box3d(box2d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d(box2d) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_to_BOX3D'; | |
ALTER FUNCTION public.box3d(box2d) OWNER TO postgres; | |
-- | |
-- TOC entry 111 (class 1255 OID 18464) | |
-- Dependencies: 1090 6 1093 | |
-- Name: box3d_extent(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3d_extent(box3d_extent) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_extent_to_BOX3D'; | |
ALTER FUNCTION public.box3d_extent(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 112 (class 1255 OID 18465) | |
-- Dependencies: 6 1090 | |
-- Name: box3dtobox(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION box3dtobox(box3d) RETURNS box | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT box($1)$_$; | |
ALTER FUNCTION public.box3dtobox(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 113 (class 1255 OID 18466) | |
-- Dependencies: 1102 6 1102 | |
-- Name: buffer(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION buffer(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'buffer'; | |
ALTER FUNCTION public.buffer(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 114 (class 1255 OID 18467) | |
-- Dependencies: 1102 6 1102 | |
-- Name: buffer(geometry, double precision, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION buffer(geometry, double precision, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_Buffer($1, $2, $3)$_$; | |
ALTER FUNCTION public.buffer(geometry, double precision, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 115 (class 1255 OID 18468) | |
-- Dependencies: 1102 6 1102 | |
-- Name: buildarea(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION buildarea(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_buildarea'; | |
ALTER FUNCTION public.buildarea(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 116 (class 1255 OID 18469) | |
-- Dependencies: 6 1102 | |
-- Name: bytea(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION bytea(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_bytea'; | |
ALTER FUNCTION public.bytea(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 117 (class 1255 OID 18470) | |
-- Dependencies: 6 1102 1102 | |
-- Name: centroid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION centroid(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'centroid'; | |
ALTER FUNCTION public.centroid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 119 (class 1255 OID 18472) | |
-- Dependencies: 6 | |
-- Name: checkauth(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION checkauth(text, text) RETURNS integer | |
LANGUAGE sql | |
AS $_$ SELECT CheckAuth('', $1, $2) $_$; | |
ALTER FUNCTION public.checkauth(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 118 (class 1255 OID 18471) | |
-- Dependencies: 1170 6 | |
-- Name: checkauth(text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION checkauth(text, text, text) RETURNS integer | |
LANGUAGE plpgsql | |
AS $_$ | |
DECLARE | |
schema text; | |
BEGIN | |
IF NOT LongTransactionsEnabled() THEN | |
RAISE EXCEPTION 'Long transaction support disabled, use EnableLongTransaction() to enable.'; | |
END IF; | |
if ( $1 != '' ) THEN | |
schema = $1; | |
ELSE | |
SELECT current_schema() into schema; | |
END IF; | |
-- TODO: check for an already existing trigger ? | |
EXECUTE 'CREATE TRIGGER check_auth BEFORE UPDATE OR DELETE ON ' | |
|| quote_ident(schema) || '.' || quote_ident($2) | |
||' FOR EACH ROW EXECUTE PROCEDURE CheckAuthTrigger(' | |
|| quote_literal($3) || ')'; | |
RETURN 0; | |
END; | |
$_$; | |
ALTER FUNCTION public.checkauth(text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 120 (class 1255 OID 18473) | |
-- Dependencies: 6 | |
-- Name: checkauthtrigger(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION checkauthtrigger() RETURNS trigger | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'check_authorization'; | |
ALTER FUNCTION public.checkauthtrigger() OWNER TO postgres; | |
-- | |
-- TOC entry 121 (class 1255 OID 18474) | |
-- Dependencies: 1102 1102 6 1102 | |
-- Name: collect(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION collect(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'LWGEOM_collect'; | |
ALTER FUNCTION public.collect(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 122 (class 1255 OID 18475) | |
-- Dependencies: 1102 1087 1087 6 | |
-- Name: combine_bbox(box2d, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION combine_bbox(box2d, geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_combine'; | |
ALTER FUNCTION public.combine_bbox(box2d, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 123 (class 1255 OID 18476) | |
-- Dependencies: 6 1093 1102 1093 | |
-- Name: combine_bbox(box3d_extent, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION combine_bbox(box3d_extent, geometry) RETURNS box3d_extent | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'BOX3D_combine'; | |
ALTER FUNCTION public.combine_bbox(box3d_extent, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 124 (class 1255 OID 18477) | |
-- Dependencies: 6 1102 1090 1090 | |
-- Name: combine_bbox(box3d, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION combine_bbox(box3d, geometry) RETURNS box3d | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'BOX3D_combine'; | |
ALTER FUNCTION public.combine_bbox(box3d, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 125 (class 1255 OID 18478) | |
-- Dependencies: 1096 6 | |
-- Name: compression(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION compression(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getCompression'; | |
ALTER FUNCTION public.compression(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 126 (class 1255 OID 18479) | |
-- Dependencies: 1102 1102 6 | |
-- Name: contains(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION contains(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'contains'; | |
ALTER FUNCTION public.contains(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 127 (class 1255 OID 18480) | |
-- Dependencies: 1102 1102 6 | |
-- Name: convexhull(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION convexhull(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'convexhull'; | |
ALTER FUNCTION public.convexhull(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 128 (class 1255 OID 18481) | |
-- Dependencies: 6 1102 1102 | |
-- Name: crosses(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION crosses(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'crosses'; | |
ALTER FUNCTION public.crosses(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 129 (class 1255 OID 18482) | |
-- Dependencies: 6 1096 | |
-- Name: datatype(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION datatype(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getDatatype'; | |
ALTER FUNCTION public.datatype(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 130 (class 1255 OID 18483) | |
-- Dependencies: 1102 1102 6 1102 | |
-- Name: difference(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION difference(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'difference'; | |
ALTER FUNCTION public.difference(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 131 (class 1255 OID 18484) | |
-- Dependencies: 1102 6 | |
-- Name: dimension(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dimension(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dimension'; | |
ALTER FUNCTION public.dimension(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 132 (class 1255 OID 18485) | |
-- Dependencies: 1170 6 | |
-- Name: disablelongtransactions(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION disablelongtransactions() RETURNS text | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
rec RECORD; | |
BEGIN | |
-- | |
-- Drop all triggers applied by CheckAuth() | |
-- | |
FOR rec IN | |
SELECT c.relname, t.tgname, t.tgargs FROM pg_trigger t, pg_class c, pg_proc p | |
WHERE p.proname = 'checkauthtrigger' and t.tgfoid = p.oid and t.tgrelid = c.oid | |
LOOP | |
EXECUTE 'DROP TRIGGER ' || quote_ident(rec.tgname) || | |
' ON ' || quote_ident(rec.relname); | |
END LOOP; | |
-- | |
-- Drop the authorization_table table | |
-- | |
FOR rec IN SELECT * FROM pg_class WHERE relname = 'authorization_table' LOOP | |
DROP TABLE authorization_table; | |
END LOOP; | |
-- | |
-- Drop the authorized_tables view | |
-- | |
FOR rec IN SELECT * FROM pg_class WHERE relname = 'authorized_tables' LOOP | |
DROP VIEW authorized_tables; | |
END LOOP; | |
RETURN 'Long transactions support disabled'; | |
END; | |
$$; | |
ALTER FUNCTION public.disablelongtransactions() OWNER TO postgres; | |
-- | |
-- TOC entry 133 (class 1255 OID 18486) | |
-- Dependencies: 1102 6 1102 | |
-- Name: disjoint(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION disjoint(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'disjoint'; | |
ALTER FUNCTION public.disjoint(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 134 (class 1255 OID 18487) | |
-- Dependencies: 1102 6 1102 | |
-- Name: distance(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION distance(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_mindistance2d'; | |
ALTER FUNCTION public.distance(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 135 (class 1255 OID 18488) | |
-- Dependencies: 1102 6 1102 | |
-- Name: distance_sphere(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION distance_sphere(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_distance_sphere'; | |
ALTER FUNCTION public.distance_sphere(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 136 (class 1255 OID 18489) | |
-- Dependencies: 6 1102 1102 1113 | |
-- Name: distance_spheroid(geometry, geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION distance_spheroid(geometry, geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_distance_ellipsoid'; | |
ALTER FUNCTION public.distance_spheroid(geometry, geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 137 (class 1255 OID 18490) | |
-- Dependencies: 1102 6 1102 | |
-- Name: dropbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropbbox(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dropBBOX'; | |
ALTER FUNCTION public.dropbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 140 (class 1255 OID 18493) | |
-- Dependencies: 6 1170 | |
-- Name: dropgeometrycolumn(character varying, character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropgeometrycolumn(character varying, character varying) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
ret text; | |
BEGIN | |
SELECT DropGeometryColumn('','',$1,$2) into ret; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.dropgeometrycolumn(character varying, character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 139 (class 1255 OID 18492) | |
-- Dependencies: 6 1170 | |
-- Name: dropgeometrycolumn(character varying, character varying, character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropgeometrycolumn(character varying, character varying, character varying) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
ret text; | |
BEGIN | |
SELECT DropGeometryColumn('',$1,$2,$3) into ret; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.dropgeometrycolumn(character varying, character varying, character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 138 (class 1255 OID 18491) | |
-- Dependencies: 6 1170 | |
-- Name: dropgeometrycolumn(character varying, character varying, character varying, character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropgeometrycolumn(character varying, character varying, character varying, character varying) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
catalog_name alias for $1; | |
schema_name alias for $2; | |
table_name alias for $3; | |
column_name alias for $4; | |
myrec RECORD; | |
okay boolean; | |
real_schema name; | |
BEGIN | |
-- Find, check or fix schema_name | |
IF ( schema_name != '' ) THEN | |
okay = 'f'; | |
FOR myrec IN SELECT nspname FROM pg_namespace WHERE text(nspname) = schema_name LOOP | |
okay := 't'; | |
END LOOP; | |
IF ( okay <> 't' ) THEN | |
RAISE NOTICE 'Invalid schema name - using current_schema()'; | |
SELECT current_schema() into real_schema; | |
ELSE | |
real_schema = schema_name; | |
END IF; | |
ELSE | |
SELECT current_schema() into real_schema; | |
END IF; | |
-- Find out if the column is in the geometry_columns table | |
okay = 'f'; | |
FOR myrec IN SELECT * from geometry_columns where f_table_schema = text(real_schema) and f_table_name = table_name and f_geometry_column = column_name LOOP | |
okay := 't'; | |
END LOOP; | |
IF (okay <> 't') THEN | |
RAISE EXCEPTION 'column not found in geometry_columns table'; | |
RETURN 'f'; | |
END IF; | |
-- Remove ref from geometry_columns table | |
EXECUTE 'delete from geometry_columns where f_table_schema = ' || | |
quote_literal(real_schema) || ' and f_table_name = ' || | |
quote_literal(table_name) || ' and f_geometry_column = ' || | |
quote_literal(column_name); | |
-- Remove table column | |
EXECUTE 'ALTER TABLE ' || quote_ident(real_schema) || '.' || | |
quote_ident(table_name) || ' DROP COLUMN ' || | |
quote_ident(column_name); | |
RETURN real_schema || '.' || table_name || '.' || column_name ||' effectively removed.'; | |
END; | |
$_$; | |
ALTER FUNCTION public.dropgeometrycolumn(character varying, character varying, character varying, character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 143 (class 1255 OID 18496) | |
-- Dependencies: 6 | |
-- Name: dropgeometrytable(character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropgeometrytable(character varying) RETURNS text | |
LANGUAGE sql STRICT | |
AS $_$ SELECT DropGeometryTable('','',$1) $_$; | |
ALTER FUNCTION public.dropgeometrytable(character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 142 (class 1255 OID 18495) | |
-- Dependencies: 6 | |
-- Name: dropgeometrytable(character varying, character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropgeometrytable(character varying, character varying) RETURNS text | |
LANGUAGE sql STRICT | |
AS $_$ SELECT DropGeometryTable('',$1,$2) $_$; | |
ALTER FUNCTION public.dropgeometrytable(character varying, character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 141 (class 1255 OID 18494) | |
-- Dependencies: 1170 6 | |
-- Name: dropgeometrytable(character varying, character varying, character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dropgeometrytable(character varying, character varying, character varying) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
catalog_name alias for $1; | |
schema_name alias for $2; | |
table_name alias for $3; | |
real_schema name; | |
BEGIN | |
IF ( schema_name = '' ) THEN | |
SELECT current_schema() into real_schema; | |
ELSE | |
real_schema = schema_name; | |
END IF; | |
-- Remove refs from geometry_columns table | |
EXECUTE 'DELETE FROM geometry_columns WHERE ' || | |
'f_table_schema = ' || quote_literal(real_schema) || | |
' AND ' || | |
' f_table_name = ' || quote_literal(table_name); | |
-- Remove table | |
EXECUTE 'DROP TABLE ' | |
|| quote_ident(real_schema) || '.' || | |
quote_ident(table_name); | |
RETURN | |
real_schema || '.' || | |
table_name ||' dropped.'; | |
END; | |
$_$; | |
ALTER FUNCTION public.dropgeometrytable(character varying, character varying, character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 144 (class 1255 OID 18497) | |
-- Dependencies: 6 1102 1105 | |
-- Name: dump(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dump(geometry) RETURNS SETOF geometry_dump | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dump'; | |
ALTER FUNCTION public.dump(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 145 (class 1255 OID 18498) | |
-- Dependencies: 1105 6 1102 | |
-- Name: dumprings(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION dumprings(geometry) RETURNS SETOF geometry_dump | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dump_rings'; | |
ALTER FUNCTION public.dumprings(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 146 (class 1255 OID 18499) | |
-- Dependencies: 1170 6 | |
-- Name: enablelongtransactions(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION enablelongtransactions() RETURNS text | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
"query" text; | |
exists bool; | |
rec RECORD; | |
BEGIN | |
exists = 'f'; | |
FOR rec IN SELECT * FROM pg_class WHERE relname = 'authorization_table' | |
LOOP | |
exists = 't'; | |
END LOOP; | |
IF NOT exists | |
THEN | |
"query" = 'CREATE TABLE authorization_table ( | |
toid oid, -- table oid | |
rid text, -- row id | |
expires timestamp, | |
authid text | |
)'; | |
EXECUTE "query"; | |
END IF; | |
exists = 'f'; | |
FOR rec IN SELECT * FROM pg_class WHERE relname = 'authorized_tables' | |
LOOP | |
exists = 't'; | |
END LOOP; | |
IF NOT exists THEN | |
"query" = 'CREATE VIEW authorized_tables AS ' || | |
'SELECT ' || | |
'n.nspname as schema, ' || | |
'c.relname as table, trim(' || | |
quote_literal(chr(92) || '000') || | |
' from t.tgargs) as id_column ' || | |
'FROM pg_trigger t, pg_class c, pg_proc p ' || | |
', pg_namespace n ' || | |
'WHERE p.proname = ' || quote_literal('checkauthtrigger') || | |
' AND c.relnamespace = n.oid' || | |
' AND t.tgfoid = p.oid and t.tgrelid = c.oid'; | |
EXECUTE "query"; | |
END IF; | |
RETURN 'Long transactions support enabled'; | |
END; | |
$$; | |
ALTER FUNCTION public.enablelongtransactions() OWNER TO postgres; | |
-- | |
-- TOC entry 147 (class 1255 OID 18500) | |
-- Dependencies: 6 1102 1102 | |
-- Name: endpoint(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION endpoint(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_endpoint_linestring'; | |
ALTER FUNCTION public.endpoint(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 148 (class 1255 OID 18501) | |
-- Dependencies: 1102 6 1102 | |
-- Name: envelope(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION envelope(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_envelope'; | |
ALTER FUNCTION public.envelope(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 149 (class 1255 OID 18502) | |
-- Dependencies: 6 1102 1102 | |
-- Name: equals(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION equals(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geomequals'; | |
ALTER FUNCTION public.equals(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 151 (class 1255 OID 18504) | |
-- Dependencies: 6 1087 | |
-- Name: estimated_extent(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION estimated_extent(text, text) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT SECURITY DEFINER | |
AS '$libdir/postgis-1.5', 'LWGEOM_estimated_extent'; | |
ALTER FUNCTION public.estimated_extent(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 150 (class 1255 OID 18503) | |
-- Dependencies: 1087 6 | |
-- Name: estimated_extent(text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION estimated_extent(text, text, text) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT SECURITY DEFINER | |
AS '$libdir/postgis-1.5', 'LWGEOM_estimated_extent'; | |
ALTER FUNCTION public.estimated_extent(text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 152 (class 1255 OID 18505) | |
-- Dependencies: 1090 6 1090 | |
-- Name: expand(box3d, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION expand(box3d, double precision) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_expand'; | |
ALTER FUNCTION public.expand(box3d, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 153 (class 1255 OID 18506) | |
-- Dependencies: 1087 1087 6 | |
-- Name: expand(box2d, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION expand(box2d, double precision) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_expand'; | |
ALTER FUNCTION public.expand(box2d, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 154 (class 1255 OID 18507) | |
-- Dependencies: 6 1102 1102 | |
-- Name: expand(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION expand(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_expand'; | |
ALTER FUNCTION public.expand(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 155 (class 1255 OID 18508) | |
-- Dependencies: 6 1102 1102 | |
-- Name: exteriorring(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION exteriorring(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_exteriorring_polygon'; | |
ALTER FUNCTION public.exteriorring(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 156 (class 1255 OID 18509) | |
-- Dependencies: 1096 6 | |
-- Name: factor(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION factor(chip) RETURNS real | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getFactor'; | |
ALTER FUNCTION public.factor(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 158 (class 1255 OID 18511) | |
-- Dependencies: 1087 6 1170 | |
-- Name: find_extent(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION find_extent(text, text) RETURNS box2d | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
tablename alias for $1; | |
columnname alias for $2; | |
myrec RECORD; | |
BEGIN | |
FOR myrec IN EXECUTE 'SELECT extent("' || columnname || '") FROM "' || tablename || '"' LOOP | |
return myrec.extent; | |
END LOOP; | |
END; | |
$_$; | |
ALTER FUNCTION public.find_extent(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 157 (class 1255 OID 18510) | |
-- Dependencies: 6 1170 1087 | |
-- Name: find_extent(text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION find_extent(text, text, text) RETURNS box2d | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
schemaname alias for $1; | |
tablename alias for $2; | |
columnname alias for $3; | |
myrec RECORD; | |
BEGIN | |
FOR myrec IN EXECUTE 'SELECT extent("' || columnname || '") FROM "' || schemaname || '"."' || tablename || '"' LOOP | |
return myrec.extent; | |
END LOOP; | |
END; | |
$_$; | |
ALTER FUNCTION public.find_extent(text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 159 (class 1255 OID 18512) | |
-- Dependencies: 1170 6 | |
-- Name: find_srid(character varying, character varying, character varying); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION find_srid(character varying, character varying, character varying) RETURNS integer | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
schem text; | |
tabl text; | |
sr int4; | |
BEGIN | |
IF $1 IS NULL THEN | |
RAISE EXCEPTION 'find_srid() - schema is NULL!'; | |
END IF; | |
IF $2 IS NULL THEN | |
RAISE EXCEPTION 'find_srid() - table name is NULL!'; | |
END IF; | |
IF $3 IS NULL THEN | |
RAISE EXCEPTION 'find_srid() - column name is NULL!'; | |
END IF; | |
schem = $1; | |
tabl = $2; | |
-- if the table contains a . and the schema is empty | |
-- split the table into a schema and a table | |
-- otherwise drop through to default behavior | |
IF ( schem = '' and tabl LIKE '%.%' ) THEN | |
schem = substr(tabl,1,strpos(tabl,'.')-1); | |
tabl = substr(tabl,length(schem)+2); | |
ELSE | |
schem = schem || '%'; | |
END IF; | |
select SRID into sr from geometry_columns where f_table_schema like schem and f_table_name = tabl and f_geometry_column = $3; | |
IF NOT FOUND THEN | |
RAISE EXCEPTION 'find_srid() - couldnt find the corresponding SRID - is the geometry registered in the GEOMETRY_COLUMNS table? Is there an uppercase/lowercase missmatch?'; | |
END IF; | |
return sr; | |
END; | |
$_$; | |
ALTER FUNCTION public.find_srid(character varying, character varying, character varying) OWNER TO postgres; | |
-- | |
-- TOC entry 160 (class 1255 OID 18513) | |
-- Dependencies: 1170 6 | |
-- Name: fix_geometry_columns(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION fix_geometry_columns() RETURNS text | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
mislinked record; | |
result text; | |
linked integer; | |
deleted integer; | |
foundschema integer; | |
BEGIN | |
-- Since 7.3 schema support has been added. | |
-- Previous postgis versions used to put the database name in | |
-- the schema column. This needs to be fixed, so we try to | |
-- set the correct schema for each geometry_colums record | |
-- looking at table, column, type and srid. | |
UPDATE geometry_columns SET f_table_schema = n.nspname | |
FROM pg_namespace n, pg_class c, pg_attribute a, | |
pg_constraint sridcheck, pg_constraint typecheck | |
WHERE ( f_table_schema is NULL | |
OR f_table_schema = '' | |
OR f_table_schema NOT IN ( | |
SELECT nspname::varchar | |
FROM pg_namespace nn, pg_class cc, pg_attribute aa | |
WHERE cc.relnamespace = nn.oid | |
AND cc.relname = f_table_name::name | |
AND aa.attrelid = cc.oid | |
AND aa.attname = f_geometry_column::name)) | |
AND f_table_name::name = c.relname | |
AND c.oid = a.attrelid | |
AND c.relnamespace = n.oid | |
AND f_geometry_column::name = a.attname | |
AND sridcheck.conrelid = c.oid | |
AND sridcheck.consrc LIKE '(srid(% = %)' | |
AND sridcheck.consrc ~ textcat(' = ', srid::text) | |
AND typecheck.conrelid = c.oid | |
AND typecheck.consrc LIKE | |
'((geometrytype(%) = ''%''::text) OR (% IS NULL))' | |
AND typecheck.consrc ~ textcat(' = ''', type::text) | |
AND NOT EXISTS ( | |
SELECT oid FROM geometry_columns gc | |
WHERE c.relname::varchar = gc.f_table_name | |
AND n.nspname::varchar = gc.f_table_schema | |
AND a.attname::varchar = gc.f_geometry_column | |
); | |
GET DIAGNOSTICS foundschema = ROW_COUNT; | |
-- no linkage to system table needed | |
return 'fixed:'||foundschema::text; | |
END; | |
$$; | |
ALTER FUNCTION public.fix_geometry_columns() OWNER TO postgres; | |
-- | |
-- TOC entry 161 (class 1255 OID 18514) | |
-- Dependencies: 1102 1102 6 | |
-- Name: force_2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION force_2d(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_2d'; | |
ALTER FUNCTION public.force_2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 162 (class 1255 OID 18515) | |
-- Dependencies: 1102 6 1102 | |
-- Name: force_3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION force_3d(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_3dz'; | |
ALTER FUNCTION public.force_3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 163 (class 1255 OID 18516) | |
-- Dependencies: 6 1102 1102 | |
-- Name: force_3dm(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION force_3dm(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_3dm'; | |
ALTER FUNCTION public.force_3dm(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 164 (class 1255 OID 18517) | |
-- Dependencies: 6 1102 1102 | |
-- Name: force_3dz(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION force_3dz(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_3dz'; | |
ALTER FUNCTION public.force_3dz(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 165 (class 1255 OID 18518) | |
-- Dependencies: 6 1102 1102 | |
-- Name: force_4d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION force_4d(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_4d'; | |
ALTER FUNCTION public.force_4d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 166 (class 1255 OID 18519) | |
-- Dependencies: 6 1102 1102 | |
-- Name: force_collection(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION force_collection(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_collection'; | |
ALTER FUNCTION public.force_collection(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 167 (class 1255 OID 18520) | |
-- Dependencies: 6 1102 1102 | |
-- Name: forcerhr(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION forcerhr(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_forceRHR_poly'; | |
ALTER FUNCTION public.forcerhr(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 169 (class 1255 OID 18522) | |
-- Dependencies: 6 1099 1102 | |
-- Name: geography(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography(geometry) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_from_geometry'; | |
ALTER FUNCTION public.geography(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 168 (class 1255 OID 18521) | |
-- Dependencies: 6 1099 1099 | |
-- Name: geography(geography, integer, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography(geography, integer, boolean) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_enforce_typmod'; | |
ALTER FUNCTION public.geography(geography, integer, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 170 (class 1255 OID 18523) | |
-- Dependencies: 6 1099 1099 | |
-- Name: geography_cmp(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_cmp(geography, geography) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_cmp'; | |
ALTER FUNCTION public.geography_cmp(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 171 (class 1255 OID 18524) | |
-- Dependencies: 6 1099 1099 | |
-- Name: geography_eq(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_eq(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_eq'; | |
ALTER FUNCTION public.geography_eq(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 172 (class 1255 OID 18525) | |
-- Dependencies: 6 1099 1099 | |
-- Name: geography_ge(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_ge(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_ge'; | |
ALTER FUNCTION public.geography_ge(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 173 (class 1255 OID 18526) | |
-- Dependencies: 6 | |
-- Name: geography_gist_compress(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_compress(internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_compress'; | |
ALTER FUNCTION public.geography_gist_compress(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 174 (class 1255 OID 18527) | |
-- Dependencies: 6 1102 | |
-- Name: geography_gist_consistent(internal, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_consistent(internal, geometry, integer) RETURNS boolean | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_consistent'; | |
ALTER FUNCTION public.geography_gist_consistent(internal, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 175 (class 1255 OID 18528) | |
-- Dependencies: 6 | |
-- Name: geography_gist_decompress(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_decompress(internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_decompress'; | |
ALTER FUNCTION public.geography_gist_decompress(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 176 (class 1255 OID 18529) | |
-- Dependencies: 6 | |
-- Name: geography_gist_join_selectivity(internal, oid, internal, smallint); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_join_selectivity(internal, oid, internal, smallint) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_join_selectivity'; | |
ALTER FUNCTION public.geography_gist_join_selectivity(internal, oid, internal, smallint) OWNER TO postgres; | |
-- | |
-- TOC entry 177 (class 1255 OID 18530) | |
-- Dependencies: 6 | |
-- Name: geography_gist_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_penalty(internal, internal, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_penalty'; | |
ALTER FUNCTION public.geography_gist_penalty(internal, internal, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 178 (class 1255 OID 18531) | |
-- Dependencies: 6 | |
-- Name: geography_gist_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_picksplit(internal, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_picksplit'; | |
ALTER FUNCTION public.geography_gist_picksplit(internal, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 179 (class 1255 OID 18532) | |
-- Dependencies: 6 1087 1087 | |
-- Name: geography_gist_same(box2d, box2d, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_same(box2d, box2d, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_same'; | |
ALTER FUNCTION public.geography_gist_same(box2d, box2d, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 180 (class 1255 OID 18533) | |
-- Dependencies: 6 | |
-- Name: geography_gist_selectivity(internal, oid, internal, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_selectivity(internal, oid, internal, integer) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_selectivity'; | |
ALTER FUNCTION public.geography_gist_selectivity(internal, oid, internal, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 181 (class 1255 OID 18534) | |
-- Dependencies: 6 | |
-- Name: geography_gist_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gist_union(bytea, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'geography_gist_union'; | |
ALTER FUNCTION public.geography_gist_union(bytea, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 182 (class 1255 OID 18535) | |
-- Dependencies: 6 1099 1099 | |
-- Name: geography_gt(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_gt(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_gt'; | |
ALTER FUNCTION public.geography_gt(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 183 (class 1255 OID 18536) | |
-- Dependencies: 1099 1099 6 | |
-- Name: geography_le(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_le(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_le'; | |
ALTER FUNCTION public.geography_le(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 184 (class 1255 OID 18537) | |
-- Dependencies: 1099 1099 6 | |
-- Name: geography_lt(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_lt(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_lt'; | |
ALTER FUNCTION public.geography_lt(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 185 (class 1255 OID 18538) | |
-- Dependencies: 1099 1099 6 | |
-- Name: geography_overlaps(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_overlaps(geography, geography) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_overlaps'; | |
ALTER FUNCTION public.geography_overlaps(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 186 (class 1255 OID 18539) | |
-- Dependencies: 6 | |
-- Name: geography_typmod_dims(integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_typmod_dims(integer) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_typmod_dims'; | |
ALTER FUNCTION public.geography_typmod_dims(integer) OWNER TO postgres; | |
-- | |
-- TOC entry 187 (class 1255 OID 18540) | |
-- Dependencies: 6 | |
-- Name: geography_typmod_srid(integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_typmod_srid(integer) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_typmod_srid'; | |
ALTER FUNCTION public.geography_typmod_srid(integer) OWNER TO postgres; | |
-- | |
-- TOC entry 188 (class 1255 OID 18541) | |
-- Dependencies: 6 | |
-- Name: geography_typmod_type(integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geography_typmod_type(integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_typmod_type'; | |
ALTER FUNCTION public.geography_typmod_type(integer) OWNER TO postgres; | |
-- | |
-- TOC entry 190 (class 1255 OID 18543) | |
-- Dependencies: 6 1102 | |
-- Name: geomcollfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomcollfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromText($1)) = 'GEOMETRYCOLLECTION' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.geomcollfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 189 (class 1255 OID 18542) | |
-- Dependencies: 6 1102 | |
-- Name: geomcollfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomcollfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromText($1, $2)) = 'GEOMETRYCOLLECTION' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.geomcollfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 192 (class 1255 OID 18545) | |
-- Dependencies: 6 1102 | |
-- Name: geomcollfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomcollfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromWKB($1)) = 'GEOMETRYCOLLECTION' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.geomcollfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 191 (class 1255 OID 18544) | |
-- Dependencies: 6 1102 | |
-- Name: geomcollfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomcollfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromWKB($1, $2)) = 'GEOMETRYCOLLECTION' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.geomcollfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 193 (class 1255 OID 18546) | |
-- Dependencies: 6 1093 1102 | |
-- Name: geometry(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(box3d_extent) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_LWGEOM'; | |
ALTER FUNCTION public.geometry(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 194 (class 1255 OID 18547) | |
-- Dependencies: 6 1102 1087 | |
-- Name: geometry(box2d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(box2d) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_to_LWGEOM'; | |
ALTER FUNCTION public.geometry(box2d) OWNER TO postgres; | |
-- | |
-- TOC entry 195 (class 1255 OID 18548) | |
-- Dependencies: 6 1102 1090 | |
-- Name: geometry(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(box3d) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_LWGEOM'; | |
ALTER FUNCTION public.geometry(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 196 (class 1255 OID 18549) | |
-- Dependencies: 6 1102 | |
-- Name: geometry(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'parse_WKT_lwgeom'; | |
ALTER FUNCTION public.geometry(text) OWNER TO postgres; | |
-- | |
-- TOC entry 197 (class 1255 OID 18550) | |
-- Dependencies: 6 1102 1096 | |
-- Name: geometry(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(chip) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_to_LWGEOM'; | |
ALTER FUNCTION public.geometry(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 198 (class 1255 OID 18551) | |
-- Dependencies: 6 1102 | |
-- Name: geometry(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_bytea'; | |
ALTER FUNCTION public.geometry(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 199 (class 1255 OID 18552) | |
-- Dependencies: 6 1102 1099 | |
-- Name: geometry(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry(geography) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geometry_from_geography'; | |
ALTER FUNCTION public.geometry(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 200 (class 1255 OID 18553) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_above(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_above(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_above'; | |
ALTER FUNCTION public.geometry_above(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 201 (class 1255 OID 18554) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_below(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_below(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_below'; | |
ALTER FUNCTION public.geometry_below(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 202 (class 1255 OID 18555) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_cmp(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_cmp(geometry, geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_cmp'; | |
ALTER FUNCTION public.geometry_cmp(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 203 (class 1255 OID 18556) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_contain(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_contain(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_contain'; | |
ALTER FUNCTION public.geometry_contain(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 204 (class 1255 OID 18557) | |
-- Dependencies: 1102 1102 6 | |
-- Name: geometry_contained(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_contained(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_contained'; | |
ALTER FUNCTION public.geometry_contained(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 205 (class 1255 OID 18558) | |
-- Dependencies: 1102 1102 6 | |
-- Name: geometry_eq(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_eq(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_eq'; | |
ALTER FUNCTION public.geometry_eq(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 206 (class 1255 OID 18559) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_ge(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_ge(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_ge'; | |
ALTER FUNCTION public.geometry_ge(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 207 (class 1255 OID 18560) | |
-- Dependencies: 6 | |
-- Name: geometry_gist_joinsel(internal, oid, internal, smallint); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_gist_joinsel(internal, oid, internal, smallint) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_joinsel'; | |
ALTER FUNCTION public.geometry_gist_joinsel(internal, oid, internal, smallint) OWNER TO postgres; | |
-- | |
-- TOC entry 208 (class 1255 OID 18561) | |
-- Dependencies: 6 | |
-- Name: geometry_gist_sel(internal, oid, internal, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_gist_sel(internal, oid, internal, integer) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_sel'; | |
ALTER FUNCTION public.geometry_gist_sel(internal, oid, internal, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 209 (class 1255 OID 18562) | |
-- Dependencies: 1102 6 1102 | |
-- Name: geometry_gt(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_gt(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_gt'; | |
ALTER FUNCTION public.geometry_gt(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 210 (class 1255 OID 18563) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_le(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_le(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_le'; | |
ALTER FUNCTION public.geometry_le(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 211 (class 1255 OID 18564) | |
-- Dependencies: 1102 1102 6 | |
-- Name: geometry_left(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_left(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_left'; | |
ALTER FUNCTION public.geometry_left(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 212 (class 1255 OID 18565) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_lt(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_lt(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_lt'; | |
ALTER FUNCTION public.geometry_lt(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 213 (class 1255 OID 18566) | |
-- Dependencies: 1102 6 1102 | |
-- Name: geometry_overabove(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_overabove(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overabove'; | |
ALTER FUNCTION public.geometry_overabove(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 214 (class 1255 OID 18567) | |
-- Dependencies: 1102 1102 6 | |
-- Name: geometry_overbelow(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_overbelow(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overbelow'; | |
ALTER FUNCTION public.geometry_overbelow(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 215 (class 1255 OID 18568) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_overlap(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_overlap(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overlap'; | |
ALTER FUNCTION public.geometry_overlap(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 216 (class 1255 OID 18569) | |
-- Dependencies: 1102 6 1102 | |
-- Name: geometry_overleft(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_overleft(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overleft'; | |
ALTER FUNCTION public.geometry_overleft(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 217 (class 1255 OID 18570) | |
-- Dependencies: 1102 6 1102 | |
-- Name: geometry_overright(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_overright(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overright'; | |
ALTER FUNCTION public.geometry_overright(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 218 (class 1255 OID 18571) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_right(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_right(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_right'; | |
ALTER FUNCTION public.geometry_right(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 219 (class 1255 OID 18572) | |
-- Dependencies: 1102 6 1102 | |
-- Name: geometry_same(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_same(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_samebox'; | |
ALTER FUNCTION public.geometry_same(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 220 (class 1255 OID 18573) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometry_samebox(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometry_samebox(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_samebox'; | |
ALTER FUNCTION public.geometry_samebox(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 221 (class 1255 OID 18574) | |
-- Dependencies: 6 1102 | |
-- Name: geometryfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometryfromtext(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.geometryfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 222 (class 1255 OID 18575) | |
-- Dependencies: 6 1102 | |
-- Name: geometryfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometryfromtext(text, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.geometryfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 223 (class 1255 OID 18576) | |
-- Dependencies: 6 1102 1102 | |
-- Name: geometryn(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometryn(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_geometryn_collection'; | |
ALTER FUNCTION public.geometryn(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 224 (class 1255 OID 18577) | |
-- Dependencies: 6 1102 | |
-- Name: geometrytype(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geometrytype(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_getTYPE'; | |
ALTER FUNCTION public.geometrytype(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 225 (class 1255 OID 18578) | |
-- Dependencies: 6 1102 | |
-- Name: geomfromewkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomfromewkb(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOMFromWKB'; | |
ALTER FUNCTION public.geomfromewkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 226 (class 1255 OID 18579) | |
-- Dependencies: 6 1102 | |
-- Name: geomfromewkt(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomfromewkt(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'parse_WKT_lwgeom'; | |
ALTER FUNCTION public.geomfromewkt(text) OWNER TO postgres; | |
-- | |
-- TOC entry 227 (class 1255 OID 18580) | |
-- Dependencies: 6 1102 | |
-- Name: geomfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT geometryfromtext($1)$_$; | |
ALTER FUNCTION public.geomfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 228 (class 1255 OID 18581) | |
-- Dependencies: 6 1102 | |
-- Name: geomfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT geometryfromtext($1, $2)$_$; | |
ALTER FUNCTION public.geomfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 229 (class 1255 OID 18582) | |
-- Dependencies: 6 1102 | |
-- Name: geomfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomfromwkb(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_WKB'; | |
ALTER FUNCTION public.geomfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 230 (class 1255 OID 18583) | |
-- Dependencies: 6 1102 | |
-- Name: geomfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT setSRID(GeomFromWKB($1), $2)$_$; | |
ALTER FUNCTION public.geomfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 231 (class 1255 OID 18584) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: geomunion(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION geomunion(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geomunion'; | |
ALTER FUNCTION public.geomunion(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 232 (class 1255 OID 18585) | |
-- Dependencies: 6 1170 | |
-- Name: get_proj4_from_srid(integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION get_proj4_from_srid(integer) RETURNS text | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
BEGIN | |
RETURN proj4text::text FROM spatial_ref_sys WHERE srid= $1; | |
END; | |
$_$; | |
ALTER FUNCTION public.get_proj4_from_srid(integer) OWNER TO postgres; | |
-- | |
-- TOC entry 233 (class 1255 OID 18586) | |
-- Dependencies: 6 1087 1102 | |
-- Name: getbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION getbbox(geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.getbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 234 (class 1255 OID 18587) | |
-- Dependencies: 6 1102 | |
-- Name: getsrid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION getsrid(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_getSRID'; | |
ALTER FUNCTION public.getsrid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 235 (class 1255 OID 18588) | |
-- Dependencies: 6 | |
-- Name: gettransactionid(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION gettransactionid() RETURNS xid | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'getTransactionID'; | |
ALTER FUNCTION public.gettransactionid() OWNER TO postgres; | |
-- | |
-- TOC entry 236 (class 1255 OID 18589) | |
-- Dependencies: 6 1102 | |
-- Name: hasbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION hasbbox(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_hasBBOX'; | |
ALTER FUNCTION public.hasbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 237 (class 1255 OID 18590) | |
-- Dependencies: 6 1096 | |
-- Name: height(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION height(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getHeight'; | |
ALTER FUNCTION public.height(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 238 (class 1255 OID 18591) | |
-- Dependencies: 6 1102 1102 | |
-- Name: interiorringn(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION interiorringn(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_interiorringn_polygon'; | |
ALTER FUNCTION public.interiorringn(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 239 (class 1255 OID 18592) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: intersection(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION intersection(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'intersection'; | |
ALTER FUNCTION public.intersection(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 240 (class 1255 OID 18593) | |
-- Dependencies: 6 1102 1102 | |
-- Name: intersects(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION intersects(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'intersects'; | |
ALTER FUNCTION public.intersects(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 241 (class 1255 OID 18594) | |
-- Dependencies: 6 1102 | |
-- Name: isclosed(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION isclosed(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_isclosed_linestring'; | |
ALTER FUNCTION public.isclosed(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 242 (class 1255 OID 18595) | |
-- Dependencies: 6 1102 | |
-- Name: isempty(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION isempty(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_isempty'; | |
ALTER FUNCTION public.isempty(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 243 (class 1255 OID 18596) | |
-- Dependencies: 6 1102 | |
-- Name: isring(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION isring(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'isring'; | |
ALTER FUNCTION public.isring(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 244 (class 1255 OID 18597) | |
-- Dependencies: 6 1102 | |
-- Name: issimple(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION issimple(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'issimple'; | |
ALTER FUNCTION public.issimple(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 245 (class 1255 OID 18598) | |
-- Dependencies: 6 1102 | |
-- Name: isvalid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION isvalid(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'isvalid'; | |
ALTER FUNCTION public.isvalid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 246 (class 1255 OID 18599) | |
-- Dependencies: 6 1102 | |
-- Name: length(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION length(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_linestring'; | |
ALTER FUNCTION public.length(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 247 (class 1255 OID 18600) | |
-- Dependencies: 6 1102 | |
-- Name: length2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION length2d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length2d_linestring'; | |
ALTER FUNCTION public.length2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 248 (class 1255 OID 18601) | |
-- Dependencies: 6 1102 1113 | |
-- Name: length2d_spheroid(geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION length2d_spheroid(geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_length2d_ellipsoid'; | |
ALTER FUNCTION public.length2d_spheroid(geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 249 (class 1255 OID 18602) | |
-- Dependencies: 6 1102 | |
-- Name: length3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION length3d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_linestring'; | |
ALTER FUNCTION public.length3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 250 (class 1255 OID 18603) | |
-- Dependencies: 6 1102 1113 | |
-- Name: length3d_spheroid(geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION length3d_spheroid(geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_ellipsoid_linestring'; | |
ALTER FUNCTION public.length3d_spheroid(geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 251 (class 1255 OID 18604) | |
-- Dependencies: 6 1102 1113 | |
-- Name: length_spheroid(geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION length_spheroid(geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_ellipsoid_linestring'; | |
ALTER FUNCTION public.length_spheroid(geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 252 (class 1255 OID 18605) | |
-- Dependencies: 6 1102 1102 | |
-- Name: line_interpolate_point(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION line_interpolate_point(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_interpolate_point'; | |
ALTER FUNCTION public.line_interpolate_point(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 253 (class 1255 OID 18606) | |
-- Dependencies: 6 1102 1102 | |
-- Name: line_locate_point(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION line_locate_point(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_locate_point'; | |
ALTER FUNCTION public.line_locate_point(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 254 (class 1255 OID 18607) | |
-- Dependencies: 6 1102 1102 | |
-- Name: line_substring(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION line_substring(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_substring'; | |
ALTER FUNCTION public.line_substring(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 255 (class 1255 OID 18608) | |
-- Dependencies: 6 1102 1102 | |
-- Name: linefrommultipoint(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linefrommultipoint(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_from_mpoint'; | |
ALTER FUNCTION public.linefrommultipoint(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 256 (class 1255 OID 18609) | |
-- Dependencies: 6 1102 | |
-- Name: linefromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linefromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1)) = 'LINESTRING' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.linefromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 257 (class 1255 OID 18610) | |
-- Dependencies: 6 1102 | |
-- Name: linefromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linefromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1, $2)) = 'LINESTRING' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.linefromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 259 (class 1255 OID 18612) | |
-- Dependencies: 6 1102 | |
-- Name: linefromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linefromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'LINESTRING' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.linefromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 258 (class 1255 OID 18611) | |
-- Dependencies: 6 1102 | |
-- Name: linefromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linefromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'LINESTRING' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.linefromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 260 (class 1255 OID 18613) | |
-- Dependencies: 6 1102 1102 | |
-- Name: linemerge(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linemerge(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'linemerge'; | |
ALTER FUNCTION public.linemerge(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 261 (class 1255 OID 18614) | |
-- Dependencies: 1102 6 | |
-- Name: linestringfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linestringfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT LineFromText($1)$_$; | |
ALTER FUNCTION public.linestringfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 262 (class 1255 OID 18615) | |
-- Dependencies: 6 1102 | |
-- Name: linestringfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linestringfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT LineFromText($1, $2)$_$; | |
ALTER FUNCTION public.linestringfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 264 (class 1255 OID 18617) | |
-- Dependencies: 1102 6 | |
-- Name: linestringfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linestringfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'LINESTRING' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.linestringfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 263 (class 1255 OID 18616) | |
-- Dependencies: 1102 6 | |
-- Name: linestringfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION linestringfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'LINESTRING' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.linestringfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 265 (class 1255 OID 18618) | |
-- Dependencies: 1102 6 1102 | |
-- Name: locate_along_measure(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION locate_along_measure(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT locate_between_measures($1, $2, $2) $_$; | |
ALTER FUNCTION public.locate_along_measure(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 266 (class 1255 OID 18619) | |
-- Dependencies: 6 1102 1102 | |
-- Name: locate_between_measures(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION locate_between_measures(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_locate_between_m'; | |
ALTER FUNCTION public.locate_between_measures(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 269 (class 1255 OID 18622) | |
-- Dependencies: 6 | |
-- Name: lockrow(text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lockrow(text, text, text) RETURNS integer | |
LANGUAGE sql STRICT | |
AS $_$ SELECT LockRow(current_schema(), $1, $2, $3, now()::timestamp+'1:00'); $_$; | |
ALTER FUNCTION public.lockrow(text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 268 (class 1255 OID 18621) | |
-- Dependencies: 6 | |
-- Name: lockrow(text, text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lockrow(text, text, text, text) RETURNS integer | |
LANGUAGE sql STRICT | |
AS $_$ SELECT LockRow($1, $2, $3, $4, now()::timestamp+'1:00'); $_$; | |
ALTER FUNCTION public.lockrow(text, text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 270 (class 1255 OID 18623) | |
-- Dependencies: 6 | |
-- Name: lockrow(text, text, text, timestamp without time zone); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lockrow(text, text, text, timestamp without time zone) RETURNS integer | |
LANGUAGE sql STRICT | |
AS $_$ SELECT LockRow(current_schema(), $1, $2, $3, $4); $_$; | |
ALTER FUNCTION public.lockrow(text, text, text, timestamp without time zone) OWNER TO postgres; | |
-- | |
-- TOC entry 267 (class 1255 OID 18620) | |
-- Dependencies: 6 1170 | |
-- Name: lockrow(text, text, text, text, timestamp without time zone); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lockrow(text, text, text, text, timestamp without time zone) RETURNS integer | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
myschema alias for $1; | |
mytable alias for $2; | |
myrid alias for $3; | |
authid alias for $4; | |
expires alias for $5; | |
ret int; | |
mytoid oid; | |
myrec RECORD; | |
BEGIN | |
IF NOT LongTransactionsEnabled() THEN | |
RAISE EXCEPTION 'Long transaction support disabled, use EnableLongTransaction() to enable.'; | |
END IF; | |
EXECUTE 'DELETE FROM authorization_table WHERE expires < now()'; | |
SELECT c.oid INTO mytoid FROM pg_class c, pg_namespace n | |
WHERE c.relname = mytable | |
AND c.relnamespace = n.oid | |
AND n.nspname = myschema; | |
-- RAISE NOTICE 'toid: %', mytoid; | |
FOR myrec IN SELECT * FROM authorization_table WHERE | |
toid = mytoid AND rid = myrid | |
LOOP | |
IF myrec.authid != authid THEN | |
RETURN 0; | |
ELSE | |
RETURN 1; | |
END IF; | |
END LOOP; | |
EXECUTE 'INSERT INTO authorization_table VALUES ('|| | |
quote_literal(mytoid::text)||','||quote_literal(myrid)|| | |
','||quote_literal(expires::text)|| | |
','||quote_literal(authid) ||')'; | |
GET DIAGNOSTICS ret = ROW_COUNT; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.lockrow(text, text, text, text, timestamp without time zone) OWNER TO postgres; | |
-- | |
-- TOC entry 271 (class 1255 OID 18624) | |
-- Dependencies: 1170 6 | |
-- Name: longtransactionsenabled(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION longtransactionsenabled() RETURNS boolean | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
rec RECORD; | |
BEGIN | |
FOR rec IN SELECT oid FROM pg_class WHERE relname = 'authorized_tables' | |
LOOP | |
return 't'; | |
END LOOP; | |
return 'f'; | |
END; | |
$$; | |
ALTER FUNCTION public.longtransactionsenabled() OWNER TO postgres; | |
-- | |
-- TOC entry 272 (class 1255 OID 18625) | |
-- Dependencies: 6 | |
-- Name: lwgeom_gist_compress(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_compress(internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_compress'; | |
ALTER FUNCTION public.lwgeom_gist_compress(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 273 (class 1255 OID 18626) | |
-- Dependencies: 6 1102 | |
-- Name: lwgeom_gist_consistent(internal, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_consistent(internal, geometry, integer) RETURNS boolean | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_consistent'; | |
ALTER FUNCTION public.lwgeom_gist_consistent(internal, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 274 (class 1255 OID 18627) | |
-- Dependencies: 6 | |
-- Name: lwgeom_gist_decompress(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_decompress(internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_decompress'; | |
ALTER FUNCTION public.lwgeom_gist_decompress(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 275 (class 1255 OID 18628) | |
-- Dependencies: 6 | |
-- Name: lwgeom_gist_penalty(internal, internal, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_penalty(internal, internal, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_penalty'; | |
ALTER FUNCTION public.lwgeom_gist_penalty(internal, internal, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 276 (class 1255 OID 18629) | |
-- Dependencies: 6 | |
-- Name: lwgeom_gist_picksplit(internal, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_picksplit(internal, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_picksplit'; | |
ALTER FUNCTION public.lwgeom_gist_picksplit(internal, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 277 (class 1255 OID 18630) | |
-- Dependencies: 6 1087 1087 | |
-- Name: lwgeom_gist_same(box2d, box2d, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_same(box2d, box2d, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_same'; | |
ALTER FUNCTION public.lwgeom_gist_same(box2d, box2d, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 278 (class 1255 OID 18631) | |
-- Dependencies: 6 | |
-- Name: lwgeom_gist_union(bytea, internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION lwgeom_gist_union(bytea, internal) RETURNS internal | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_union'; | |
ALTER FUNCTION public.lwgeom_gist_union(bytea, internal) OWNER TO postgres; | |
-- | |
-- TOC entry 279 (class 1255 OID 18632) | |
-- Dependencies: 6 1102 | |
-- Name: m(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION m(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_m_point'; | |
ALTER FUNCTION public.m(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 280 (class 1255 OID 18633) | |
-- Dependencies: 6 1102 1102 1087 | |
-- Name: makebox2d(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makebox2d(geometry, geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_construct'; | |
ALTER FUNCTION public.makebox2d(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 281 (class 1255 OID 18634) | |
-- Dependencies: 1090 1102 6 1102 | |
-- Name: makebox3d(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makebox3d(geometry, geometry) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_construct'; | |
ALTER FUNCTION public.makebox3d(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 282 (class 1255 OID 18635) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: makeline(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makeline(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makeline'; | |
ALTER FUNCTION public.makeline(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 283 (class 1255 OID 18636) | |
-- Dependencies: 1102 6 1104 | |
-- Name: makeline_garray(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makeline_garray(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makeline_garray'; | |
ALTER FUNCTION public.makeline_garray(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 284 (class 1255 OID 18637) | |
-- Dependencies: 1102 6 | |
-- Name: makepoint(double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makepoint(double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.makepoint(double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 285 (class 1255 OID 18638) | |
-- Dependencies: 6 1102 | |
-- Name: makepoint(double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makepoint(double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.makepoint(double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 286 (class 1255 OID 18639) | |
-- Dependencies: 6 1102 | |
-- Name: makepoint(double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makepoint(double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.makepoint(double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 287 (class 1255 OID 18640) | |
-- Dependencies: 1102 6 | |
-- Name: makepointm(double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makepointm(double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint3dm'; | |
ALTER FUNCTION public.makepointm(double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 289 (class 1255 OID 18642) | |
-- Dependencies: 1102 6 1102 | |
-- Name: makepolygon(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makepolygon(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoly'; | |
ALTER FUNCTION public.makepolygon(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 288 (class 1255 OID 18641) | |
-- Dependencies: 6 1104 1102 1102 | |
-- Name: makepolygon(geometry, geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION makepolygon(geometry, geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoly'; | |
ALTER FUNCTION public.makepolygon(geometry, geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 290 (class 1255 OID 18643) | |
-- Dependencies: 1102 6 1102 | |
-- Name: max_distance(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION max_distance(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_maxdistance2d_linestring'; | |
ALTER FUNCTION public.max_distance(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 291 (class 1255 OID 18644) | |
-- Dependencies: 6 1102 | |
-- Name: mem_size(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mem_size(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_mem_size'; | |
ALTER FUNCTION public.mem_size(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 293 (class 1255 OID 18646) | |
-- Dependencies: 6 1102 | |
-- Name: mlinefromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mlinefromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1)) = 'MULTILINESTRING' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mlinefromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 292 (class 1255 OID 18645) | |
-- Dependencies: 6 1102 | |
-- Name: mlinefromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mlinefromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromText($1, $2)) = 'MULTILINESTRING' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mlinefromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 295 (class 1255 OID 18648) | |
-- Dependencies: 1102 6 | |
-- Name: mlinefromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mlinefromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'MULTILINESTRING' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mlinefromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 294 (class 1255 OID 18647) | |
-- Dependencies: 6 1102 | |
-- Name: mlinefromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mlinefromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'MULTILINESTRING' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mlinefromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 297 (class 1255 OID 18650) | |
-- Dependencies: 6 1102 | |
-- Name: mpointfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpointfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1)) = 'MULTIPOINT' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpointfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 296 (class 1255 OID 18649) | |
-- Dependencies: 6 1102 | |
-- Name: mpointfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpointfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1,$2)) = 'MULTIPOINT' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpointfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 299 (class 1255 OID 18652) | |
-- Dependencies: 1102 6 | |
-- Name: mpointfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpointfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'MULTIPOINT' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpointfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 298 (class 1255 OID 18651) | |
-- Dependencies: 1102 6 | |
-- Name: mpointfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpointfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1,$2)) = 'MULTIPOINT' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpointfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 301 (class 1255 OID 18654) | |
-- Dependencies: 6 1102 | |
-- Name: mpolyfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpolyfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1)) = 'MULTIPOLYGON' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpolyfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 300 (class 1255 OID 18653) | |
-- Dependencies: 6 1102 | |
-- Name: mpolyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpolyfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1, $2)) = 'MULTIPOLYGON' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpolyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 303 (class 1255 OID 18656) | |
-- Dependencies: 1102 6 | |
-- Name: mpolyfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpolyfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'MULTIPOLYGON' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpolyfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 302 (class 1255 OID 18655) | |
-- Dependencies: 6 1102 | |
-- Name: mpolyfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION mpolyfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'MULTIPOLYGON' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.mpolyfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 304 (class 1255 OID 18657) | |
-- Dependencies: 6 1102 1102 | |
-- Name: multi(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multi(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_multi'; | |
ALTER FUNCTION public.multi(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 306 (class 1255 OID 18659) | |
-- Dependencies: 6 1102 | |
-- Name: multilinefromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multilinefromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'MULTILINESTRING' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.multilinefromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 305 (class 1255 OID 18658) | |
-- Dependencies: 6 1102 | |
-- Name: multilinefromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multilinefromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'MULTILINESTRING' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.multilinefromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 307 (class 1255 OID 18660) | |
-- Dependencies: 6 1102 | |
-- Name: multilinestringfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multilinestringfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_MLineFromText($1)$_$; | |
ALTER FUNCTION public.multilinestringfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 308 (class 1255 OID 18661) | |
-- Dependencies: 6 1102 | |
-- Name: multilinestringfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multilinestringfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MLineFromText($1, $2)$_$; | |
ALTER FUNCTION public.multilinestringfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 310 (class 1255 OID 18663) | |
-- Dependencies: 6 1102 | |
-- Name: multipointfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipointfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPointFromText($1)$_$; | |
ALTER FUNCTION public.multipointfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 309 (class 1255 OID 18662) | |
-- Dependencies: 1102 6 | |
-- Name: multipointfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipointfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPointFromText($1, $2)$_$; | |
ALTER FUNCTION public.multipointfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 312 (class 1255 OID 18665) | |
-- Dependencies: 6 1102 | |
-- Name: multipointfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipointfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'MULTIPOINT' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.multipointfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 311 (class 1255 OID 18664) | |
-- Dependencies: 6 1102 | |
-- Name: multipointfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipointfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1,$2)) = 'MULTIPOINT' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.multipointfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 314 (class 1255 OID 18667) | |
-- Dependencies: 6 1102 | |
-- Name: multipolyfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipolyfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'MULTIPOLYGON' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.multipolyfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 313 (class 1255 OID 18666) | |
-- Dependencies: 1102 6 | |
-- Name: multipolyfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipolyfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'MULTIPOLYGON' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.multipolyfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 316 (class 1255 OID 18669) | |
-- Dependencies: 1102 6 | |
-- Name: multipolygonfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipolygonfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPolyFromText($1)$_$; | |
ALTER FUNCTION public.multipolygonfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 315 (class 1255 OID 18668) | |
-- Dependencies: 1102 6 | |
-- Name: multipolygonfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION multipolygonfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPolyFromText($1, $2)$_$; | |
ALTER FUNCTION public.multipolygonfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 317 (class 1255 OID 18670) | |
-- Dependencies: 6 1102 | |
-- Name: ndims(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION ndims(geometry) RETURNS smallint | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_ndims'; | |
ALTER FUNCTION public.ndims(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 318 (class 1255 OID 18671) | |
-- Dependencies: 1102 6 1102 | |
-- Name: noop(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION noop(geometry) RETURNS geometry | |
LANGUAGE c STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_noop'; | |
ALTER FUNCTION public.noop(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 319 (class 1255 OID 18672) | |
-- Dependencies: 1102 6 | |
-- Name: npoints(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION npoints(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_npoints'; | |
ALTER FUNCTION public.npoints(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 320 (class 1255 OID 18673) | |
-- Dependencies: 6 1102 | |
-- Name: nrings(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION nrings(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_nrings'; | |
ALTER FUNCTION public.nrings(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 321 (class 1255 OID 18674) | |
-- Dependencies: 1102 6 | |
-- Name: numgeometries(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION numgeometries(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numgeometries_collection'; | |
ALTER FUNCTION public.numgeometries(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 322 (class 1255 OID 18675) | |
-- Dependencies: 6 1102 | |
-- Name: numinteriorring(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION numinteriorring(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numinteriorrings_polygon'; | |
ALTER FUNCTION public.numinteriorring(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 323 (class 1255 OID 18676) | |
-- Dependencies: 1102 6 | |
-- Name: numinteriorrings(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION numinteriorrings(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numinteriorrings_polygon'; | |
ALTER FUNCTION public.numinteriorrings(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 324 (class 1255 OID 18677) | |
-- Dependencies: 1102 6 | |
-- Name: numpoints(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION numpoints(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numpoints_linestring'; | |
ALTER FUNCTION public.numpoints(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 325 (class 1255 OID 18678) | |
-- Dependencies: 6 1102 1102 | |
-- Name: overlaps(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION "overlaps"(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'overlaps'; | |
ALTER FUNCTION public."overlaps"(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 326 (class 1255 OID 18679) | |
-- Dependencies: 6 1102 | |
-- Name: perimeter(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION perimeter(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_perimeter_poly'; | |
ALTER FUNCTION public.perimeter(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 327 (class 1255 OID 18680) | |
-- Dependencies: 6 1102 | |
-- Name: perimeter2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION perimeter2d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_perimeter2d_poly'; | |
ALTER FUNCTION public.perimeter2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 328 (class 1255 OID 18681) | |
-- Dependencies: 1102 6 | |
-- Name: perimeter3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION perimeter3d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_perimeter_poly'; | |
ALTER FUNCTION public.perimeter3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 329 (class 1255 OID 18682) | |
-- Dependencies: 1104 6 1110 | |
-- Name: pgis_geometry_accum_finalfn(pgis_abs); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_geometry_accum_finalfn(pgis_abs) RETURNS geometry[] | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'pgis_geometry_accum_finalfn'; | |
ALTER FUNCTION public.pgis_geometry_accum_finalfn(pgis_abs) OWNER TO postgres; | |
-- | |
-- TOC entry 330 (class 1255 OID 18683) | |
-- Dependencies: 6 1110 1110 1102 | |
-- Name: pgis_geometry_accum_transfn(pgis_abs, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_geometry_accum_transfn(pgis_abs, geometry) RETURNS pgis_abs | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'pgis_geometry_accum_transfn'; | |
ALTER FUNCTION public.pgis_geometry_accum_transfn(pgis_abs, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 331 (class 1255 OID 18684) | |
-- Dependencies: 1102 6 1110 | |
-- Name: pgis_geometry_collect_finalfn(pgis_abs); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_geometry_collect_finalfn(pgis_abs) RETURNS geometry | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'pgis_geometry_collect_finalfn'; | |
ALTER FUNCTION public.pgis_geometry_collect_finalfn(pgis_abs) OWNER TO postgres; | |
-- | |
-- TOC entry 332 (class 1255 OID 18685) | |
-- Dependencies: 6 1102 1110 | |
-- Name: pgis_geometry_makeline_finalfn(pgis_abs); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_geometry_makeline_finalfn(pgis_abs) RETURNS geometry | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'pgis_geometry_makeline_finalfn'; | |
ALTER FUNCTION public.pgis_geometry_makeline_finalfn(pgis_abs) OWNER TO postgres; | |
-- | |
-- TOC entry 333 (class 1255 OID 18686) | |
-- Dependencies: 1110 6 1102 | |
-- Name: pgis_geometry_polygonize_finalfn(pgis_abs); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_geometry_polygonize_finalfn(pgis_abs) RETURNS geometry | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'pgis_geometry_polygonize_finalfn'; | |
ALTER FUNCTION public.pgis_geometry_polygonize_finalfn(pgis_abs) OWNER TO postgres; | |
-- | |
-- TOC entry 334 (class 1255 OID 18687) | |
-- Dependencies: 1102 6 1110 | |
-- Name: pgis_geometry_union_finalfn(pgis_abs); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pgis_geometry_union_finalfn(pgis_abs) RETURNS geometry | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'pgis_geometry_union_finalfn'; | |
ALTER FUNCTION public.pgis_geometry_union_finalfn(pgis_abs) OWNER TO postgres; | |
-- | |
-- TOC entry 335 (class 1255 OID 18688) | |
-- Dependencies: 6 1102 | |
-- Name: point_inside_circle(geometry, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION point_inside_circle(geometry, double precision, double precision, double precision) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_inside_circle_point'; | |
ALTER FUNCTION public.point_inside_circle(geometry, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 336 (class 1255 OID 18689) | |
-- Dependencies: 1102 6 | |
-- Name: pointfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pointfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1)) = 'POINT' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.pointfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 337 (class 1255 OID 18690) | |
-- Dependencies: 6 1102 | |
-- Name: pointfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pointfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1, $2)) = 'POINT' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.pointfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 339 (class 1255 OID 18692) | |
-- Dependencies: 1102 6 | |
-- Name: pointfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pointfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'POINT' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.pointfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 338 (class 1255 OID 18691) | |
-- Dependencies: 6 1102 | |
-- Name: pointfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pointfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'POINT' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.pointfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 340 (class 1255 OID 18693) | |
-- Dependencies: 1102 6 1102 | |
-- Name: pointn(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pointn(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_pointn_linestring'; | |
ALTER FUNCTION public.pointn(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 341 (class 1255 OID 18694) | |
-- Dependencies: 1102 6 1102 | |
-- Name: pointonsurface(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION pointonsurface(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'pointonsurface'; | |
ALTER FUNCTION public.pointonsurface(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 342 (class 1255 OID 18695) | |
-- Dependencies: 6 1102 | |
-- Name: polyfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polyfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1)) = 'POLYGON' | |
THEN GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.polyfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 343 (class 1255 OID 18696) | |
-- Dependencies: 6 1102 | |
-- Name: polyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polyfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1, $2)) = 'POLYGON' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.polyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 345 (class 1255 OID 18698) | |
-- Dependencies: 1102 6 | |
-- Name: polyfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polyfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'POLYGON' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.polyfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 344 (class 1255 OID 18697) | |
-- Dependencies: 1102 6 | |
-- Name: polyfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polyfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'POLYGON' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.polyfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 347 (class 1255 OID 18700) | |
-- Dependencies: 6 1102 | |
-- Name: polygonfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polygonfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT PolyFromText($1)$_$; | |
ALTER FUNCTION public.polygonfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 346 (class 1255 OID 18699) | |
-- Dependencies: 6 1102 | |
-- Name: polygonfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polygonfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT PolyFromText($1, $2)$_$; | |
ALTER FUNCTION public.polygonfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 349 (class 1255 OID 18702) | |
-- Dependencies: 6 1102 | |
-- Name: polygonfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polygonfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'POLYGON' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.polygonfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 348 (class 1255 OID 18701) | |
-- Dependencies: 1102 6 | |
-- Name: polygonfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polygonfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1,$2)) = 'POLYGON' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.polygonfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 350 (class 1255 OID 18703) | |
-- Dependencies: 1104 1102 6 | |
-- Name: polygonize_garray(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION polygonize_garray(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'polygonize_garray'; | |
ALTER FUNCTION public.polygonize_garray(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 351 (class 1255 OID 18704) | |
-- Dependencies: 6 1170 | |
-- Name: populate_geometry_columns(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION populate_geometry_columns() RETURNS text | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
inserted integer; | |
oldcount integer; | |
probed integer; | |
stale integer; | |
gcs RECORD; | |
gc RECORD; | |
gsrid integer; | |
gndims integer; | |
gtype text; | |
query text; | |
gc_is_valid boolean; | |
BEGIN | |
SELECT count(*) INTO oldcount FROM geometry_columns; | |
inserted := 0; | |
EXECUTE 'TRUNCATE geometry_columns'; | |
-- Count the number of geometry columns in all tables and views | |
SELECT count(DISTINCT c.oid) INTO probed | |
FROM pg_class c, | |
pg_attribute a, | |
pg_type t, | |
pg_namespace n | |
WHERE (c.relkind = 'r' OR c.relkind = 'v') | |
AND t.typname = 'geometry' | |
AND a.attisdropped = false | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
AND n.nspname NOT ILIKE 'pg_temp%'; | |
-- Iterate through all non-dropped geometry columns | |
RAISE DEBUG 'Processing Tables.....'; | |
FOR gcs IN | |
SELECT DISTINCT ON (c.oid) c.oid, n.nspname, c.relname | |
FROM pg_class c, | |
pg_attribute a, | |
pg_type t, | |
pg_namespace n | |
WHERE c.relkind = 'r' | |
AND t.typname = 'geometry' | |
AND a.attisdropped = false | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
AND n.nspname NOT ILIKE 'pg_temp%' | |
LOOP | |
inserted := inserted + populate_geometry_columns(gcs.oid); | |
END LOOP; | |
-- Add views to geometry columns table | |
RAISE DEBUG 'Processing Views.....'; | |
FOR gcs IN | |
SELECT DISTINCT ON (c.oid) c.oid, n.nspname, c.relname | |
FROM pg_class c, | |
pg_attribute a, | |
pg_type t, | |
pg_namespace n | |
WHERE c.relkind = 'v' | |
AND t.typname = 'geometry' | |
AND a.attisdropped = false | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
LOOP | |
inserted := inserted + populate_geometry_columns(gcs.oid); | |
END LOOP; | |
IF oldcount > inserted THEN | |
stale = oldcount-inserted; | |
ELSE | |
stale = 0; | |
END IF; | |
RETURN 'probed:' ||probed|| ' inserted:'||inserted|| ' conflicts:'||probed-inserted|| ' deleted:'||stale; | |
END | |
$$; | |
ALTER FUNCTION public.populate_geometry_columns() OWNER TO postgres; | |
-- | |
-- TOC entry 352 (class 1255 OID 18705) | |
-- Dependencies: 1170 6 | |
-- Name: populate_geometry_columns(oid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION populate_geometry_columns(tbl_oid oid) RETURNS integer | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
gcs RECORD; | |
gc RECORD; | |
gsrid integer; | |
gndims integer; | |
gtype text; | |
query text; | |
gc_is_valid boolean; | |
inserted integer; | |
BEGIN | |
inserted := 0; | |
-- Iterate through all geometry columns in this table | |
FOR gcs IN | |
SELECT n.nspname, c.relname, a.attname | |
FROM pg_class c, | |
pg_attribute a, | |
pg_type t, | |
pg_namespace n | |
WHERE c.relkind = 'r' | |
AND t.typname = 'geometry' | |
AND a.attisdropped = false | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
AND n.nspname NOT ILIKE 'pg_temp%' | |
AND c.oid = tbl_oid | |
LOOP | |
RAISE DEBUG 'Processing table %.%.%', gcs.nspname, gcs.relname, gcs.attname; | |
DELETE FROM geometry_columns | |
WHERE f_table_schema = quote_ident(gcs.nspname) | |
AND f_table_name = quote_ident(gcs.relname) | |
AND f_geometry_column = quote_ident(gcs.attname); | |
gc_is_valid := true; | |
-- Try to find srid check from system tables (pg_constraint) | |
gsrid := | |
(SELECT replace(replace(split_part(s.consrc, ' = ', 2), ')', ''), '(', '') | |
FROM pg_class c, pg_namespace n, pg_attribute a, pg_constraint s | |
WHERE n.nspname = gcs.nspname | |
AND c.relname = gcs.relname | |
AND a.attname = gcs.attname | |
AND a.attrelid = c.oid | |
AND s.connamespace = n.oid | |
AND s.conrelid = c.oid | |
AND a.attnum = ANY (s.conkey) | |
AND s.consrc LIKE '%srid(% = %'); | |
IF (gsrid IS NULL) THEN | |
-- Try to find srid from the geometry itself | |
EXECUTE 'SELECT srid(' || quote_ident(gcs.attname) || ') | |
FROM ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1' | |
INTO gc; | |
gsrid := gc.srid; | |
-- Try to apply srid check to column | |
IF (gsrid IS NOT NULL) THEN | |
BEGIN | |
EXECUTE 'ALTER TABLE ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
ADD CONSTRAINT ' || quote_ident('enforce_srid_' || gcs.attname) || ' | |
CHECK (srid(' || quote_ident(gcs.attname) || ') = ' || gsrid || ')'; | |
EXCEPTION | |
WHEN check_violation THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not apply constraint CHECK (srid(%) = %)', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname), quote_ident(gcs.attname), gsrid; | |
gc_is_valid := false; | |
END; | |
END IF; | |
END IF; | |
-- Try to find ndims check from system tables (pg_constraint) | |
gndims := | |
(SELECT replace(split_part(s.consrc, ' = ', 2), ')', '') | |
FROM pg_class c, pg_namespace n, pg_attribute a, pg_constraint s | |
WHERE n.nspname = gcs.nspname | |
AND c.relname = gcs.relname | |
AND a.attname = gcs.attname | |
AND a.attrelid = c.oid | |
AND s.connamespace = n.oid | |
AND s.conrelid = c.oid | |
AND a.attnum = ANY (s.conkey) | |
AND s.consrc LIKE '%ndims(% = %'); | |
IF (gndims IS NULL) THEN | |
-- Try to find ndims from the geometry itself | |
EXECUTE 'SELECT ndims(' || quote_ident(gcs.attname) || ') | |
FROM ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1' | |
INTO gc; | |
gndims := gc.ndims; | |
-- Try to apply ndims check to column | |
IF (gndims IS NOT NULL) THEN | |
BEGIN | |
EXECUTE 'ALTER TABLE ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
ADD CONSTRAINT ' || quote_ident('enforce_dims_' || gcs.attname) || ' | |
CHECK (ndims(' || quote_ident(gcs.attname) || ') = '||gndims||')'; | |
EXCEPTION | |
WHEN check_violation THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not apply constraint CHECK (ndims(%) = %)', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname), quote_ident(gcs.attname), gndims; | |
gc_is_valid := false; | |
END; | |
END IF; | |
END IF; | |
-- Try to find geotype check from system tables (pg_constraint) | |
gtype := | |
(SELECT replace(split_part(s.consrc, '''', 2), ')', '') | |
FROM pg_class c, pg_namespace n, pg_attribute a, pg_constraint s | |
WHERE n.nspname = gcs.nspname | |
AND c.relname = gcs.relname | |
AND a.attname = gcs.attname | |
AND a.attrelid = c.oid | |
AND s.connamespace = n.oid | |
AND s.conrelid = c.oid | |
AND a.attnum = ANY (s.conkey) | |
AND s.consrc LIKE '%geometrytype(% = %'); | |
IF (gtype IS NULL) THEN | |
-- Try to find geotype from the geometry itself | |
EXECUTE 'SELECT geometrytype(' || quote_ident(gcs.attname) || ') | |
FROM ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1' | |
INTO gc; | |
gtype := gc.geometrytype; | |
--IF (gtype IS NULL) THEN | |
-- gtype := 'GEOMETRY'; | |
--END IF; | |
-- Try to apply geometrytype check to column | |
IF (gtype IS NOT NULL) THEN | |
BEGIN | |
EXECUTE 'ALTER TABLE ONLY ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
ADD CONSTRAINT ' || quote_ident('enforce_geotype_' || gcs.attname) || ' | |
CHECK ((geometrytype(' || quote_ident(gcs.attname) || ') = ' || quote_literal(gtype) || ') OR (' || quote_ident(gcs.attname) || ' IS NULL))'; | |
EXCEPTION | |
WHEN check_violation THEN | |
-- No geometry check can be applied. This column contains a number of geometry types. | |
RAISE WARNING 'Could not add geometry type check (%) to table column: %.%.%', gtype, quote_ident(gcs.nspname),quote_ident(gcs.relname),quote_ident(gcs.attname); | |
END; | |
END IF; | |
END IF; | |
IF (gsrid IS NULL) THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not determine the srid', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname); | |
ELSIF (gndims IS NULL) THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not determine the number of dimensions', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname); | |
ELSIF (gtype IS NULL) THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not determine the geometry type', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname); | |
ELSE | |
-- Only insert into geometry_columns if table constraints could be applied. | |
IF (gc_is_valid) THEN | |
INSERT INTO geometry_columns (f_table_catalog,f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, type) | |
VALUES ('', gcs.nspname, gcs.relname, gcs.attname, gndims, gsrid, gtype); | |
inserted := inserted + 1; | |
END IF; | |
END IF; | |
END LOOP; | |
-- Add views to geometry columns table | |
FOR gcs IN | |
SELECT n.nspname, c.relname, a.attname | |
FROM pg_class c, | |
pg_attribute a, | |
pg_type t, | |
pg_namespace n | |
WHERE c.relkind = 'v' | |
AND t.typname = 'geometry' | |
AND a.attisdropped = false | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
AND n.nspname NOT ILIKE 'pg_temp%' | |
AND c.oid = tbl_oid | |
LOOP | |
RAISE DEBUG 'Processing view %.%.%', gcs.nspname, gcs.relname, gcs.attname; | |
EXECUTE 'SELECT ndims(' || quote_ident(gcs.attname) || ') | |
FROM ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1' | |
INTO gc; | |
gndims := gc.ndims; | |
EXECUTE 'SELECT srid(' || quote_ident(gcs.attname) || ') | |
FROM ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1' | |
INTO gc; | |
gsrid := gc.srid; | |
EXECUTE 'SELECT geometrytype(' || quote_ident(gcs.attname) || ') | |
FROM ' || quote_ident(gcs.nspname) || '.' || quote_ident(gcs.relname) || ' | |
WHERE ' || quote_ident(gcs.attname) || ' IS NOT NULL LIMIT 1' | |
INTO gc; | |
gtype := gc.geometrytype; | |
IF (gndims IS NULL) THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not determine ndims', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname); | |
ELSIF (gsrid IS NULL) THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not determine srid', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname); | |
ELSIF (gtype IS NULL) THEN | |
RAISE WARNING 'Not inserting ''%'' in ''%.%'' into geometry_columns: could not determine gtype', quote_ident(gcs.attname), quote_ident(gcs.nspname), quote_ident(gcs.relname); | |
ELSE | |
query := 'INSERT INTO geometry_columns (f_table_catalog,f_table_schema, f_table_name, f_geometry_column, coord_dimension, srid, type) ' || | |
'VALUES ('''', ' || quote_literal(gcs.nspname) || ',' || quote_literal(gcs.relname) || ',' || quote_literal(gcs.attname) || ',' || gndims || ',' || gsrid || ',' || quote_literal(gtype) || ')'; | |
EXECUTE query; | |
inserted := inserted + 1; | |
END IF; | |
END LOOP; | |
RETURN inserted; | |
END | |
$$; | |
ALTER FUNCTION public.populate_geometry_columns(tbl_oid oid) OWNER TO postgres; | |
-- | |
-- TOC entry 353 (class 1255 OID 18707) | |
-- Dependencies: 1102 1102 6 | |
-- Name: postgis_addbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_addbbox(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_addBBOX'; | |
ALTER FUNCTION public.postgis_addbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 354 (class 1255 OID 18708) | |
-- Dependencies: 6 | |
-- Name: postgis_cache_bbox(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_cache_bbox() RETURNS trigger | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'cache_bbox'; | |
ALTER FUNCTION public.postgis_cache_bbox() OWNER TO postgres; | |
-- | |
-- TOC entry 355 (class 1255 OID 18709) | |
-- Dependencies: 1102 6 1102 | |
-- Name: postgis_dropbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_dropbbox(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dropBBOX'; | |
ALTER FUNCTION public.postgis_dropbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 356 (class 1255 OID 18710) | |
-- Dependencies: 1170 6 | |
-- Name: postgis_full_version(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_full_version() RETURNS text | |
LANGUAGE plpgsql IMMUTABLE | |
AS $$ | |
DECLARE | |
libver text; | |
projver text; | |
geosver text; | |
libxmlver text; | |
usestats bool; | |
dbproc text; | |
relproc text; | |
fullver text; | |
BEGIN | |
SELECT postgis_lib_version() INTO libver; | |
SELECT postgis_proj_version() INTO projver; | |
SELECT postgis_geos_version() INTO geosver; | |
SELECT postgis_libxml_version() INTO libxmlver; | |
SELECT postgis_uses_stats() INTO usestats; | |
SELECT postgis_scripts_installed() INTO dbproc; | |
SELECT postgis_scripts_released() INTO relproc; | |
fullver = 'POSTGIS="' || libver || '"'; | |
IF geosver IS NOT NULL THEN | |
fullver = fullver || ' GEOS="' || geosver || '"'; | |
END IF; | |
IF projver IS NOT NULL THEN | |
fullver = fullver || ' PROJ="' || projver || '"'; | |
END IF; | |
IF libxmlver IS NOT NULL THEN | |
fullver = fullver || ' LIBXML="' || libxmlver || '"'; | |
END IF; | |
IF usestats THEN | |
fullver = fullver || ' USE_STATS'; | |
END IF; | |
-- fullver = fullver || ' DBPROC="' || dbproc || '"'; | |
-- fullver = fullver || ' RELPROC="' || relproc || '"'; | |
IF dbproc != relproc THEN | |
fullver = fullver || ' (procs from ' || dbproc || ' need upgrade)'; | |
END IF; | |
RETURN fullver; | |
END | |
$$; | |
ALTER FUNCTION public.postgis_full_version() OWNER TO postgres; | |
-- | |
-- TOC entry 357 (class 1255 OID 18711) | |
-- Dependencies: 6 | |
-- Name: postgis_geos_version(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_geos_version() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_geos_version'; | |
ALTER FUNCTION public.postgis_geos_version() OWNER TO postgres; | |
-- | |
-- TOC entry 358 (class 1255 OID 18712) | |
-- Dependencies: 1087 6 1102 | |
-- Name: postgis_getbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_getbbox(geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.postgis_getbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 359 (class 1255 OID 18713) | |
-- Dependencies: 6 | |
-- Name: postgis_gist_joinsel(internal, oid, internal, smallint); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_gist_joinsel(internal, oid, internal, smallint) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_joinsel'; | |
ALTER FUNCTION public.postgis_gist_joinsel(internal, oid, internal, smallint) OWNER TO postgres; | |
-- | |
-- TOC entry 360 (class 1255 OID 18714) | |
-- Dependencies: 6 | |
-- Name: postgis_gist_sel(internal, oid, internal, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_gist_sel(internal, oid, internal, integer) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_sel'; | |
ALTER FUNCTION public.postgis_gist_sel(internal, oid, internal, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 361 (class 1255 OID 18715) | |
-- Dependencies: 6 1102 | |
-- Name: postgis_hasbbox(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_hasbbox(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_hasBBOX'; | |
ALTER FUNCTION public.postgis_hasbbox(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 362 (class 1255 OID 18716) | |
-- Dependencies: 6 | |
-- Name: postgis_lib_build_date(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_lib_build_date() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_lib_build_date'; | |
ALTER FUNCTION public.postgis_lib_build_date() OWNER TO postgres; | |
-- | |
-- TOC entry 363 (class 1255 OID 18717) | |
-- Dependencies: 6 | |
-- Name: postgis_lib_version(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_lib_version() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_lib_version'; | |
ALTER FUNCTION public.postgis_lib_version() OWNER TO postgres; | |
-- | |
-- TOC entry 364 (class 1255 OID 18718) | |
-- Dependencies: 6 | |
-- Name: postgis_libxml_version(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_libxml_version() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_libxml_version'; | |
ALTER FUNCTION public.postgis_libxml_version() OWNER TO postgres; | |
-- | |
-- TOC entry 365 (class 1255 OID 18719) | |
-- Dependencies: 1102 1102 6 | |
-- Name: postgis_noop(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_noop(geometry) RETURNS geometry | |
LANGUAGE c STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_noop'; | |
ALTER FUNCTION public.postgis_noop(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 366 (class 1255 OID 18720) | |
-- Dependencies: 6 | |
-- Name: postgis_proj_version(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_proj_version() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_proj_version'; | |
ALTER FUNCTION public.postgis_proj_version() OWNER TO postgres; | |
-- | |
-- TOC entry 367 (class 1255 OID 18721) | |
-- Dependencies: 6 | |
-- Name: postgis_scripts_build_date(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_scripts_build_date() RETURNS text | |
LANGUAGE sql IMMUTABLE | |
AS $$SELECT '2010-03-11 19:15:17'::text AS version$$; | |
ALTER FUNCTION public.postgis_scripts_build_date() OWNER TO postgres; | |
-- | |
-- TOC entry 368 (class 1255 OID 18722) | |
-- Dependencies: 6 | |
-- Name: postgis_scripts_installed(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_scripts_installed() RETURNS text | |
LANGUAGE sql IMMUTABLE | |
AS $$SELECT '1.5 r5385'::text AS version$$; | |
ALTER FUNCTION public.postgis_scripts_installed() OWNER TO postgres; | |
-- | |
-- TOC entry 369 (class 1255 OID 18723) | |
-- Dependencies: 6 | |
-- Name: postgis_scripts_released(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_scripts_released() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_scripts_released'; | |
ALTER FUNCTION public.postgis_scripts_released() OWNER TO postgres; | |
-- | |
-- TOC entry 370 (class 1255 OID 18724) | |
-- Dependencies: 6 1102 1102 | |
-- Name: postgis_transform_geometry(geometry, text, text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_transform_geometry(geometry, text, text, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'transform_geom'; | |
ALTER FUNCTION public.postgis_transform_geometry(geometry, text, text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 371 (class 1255 OID 18725) | |
-- Dependencies: 6 | |
-- Name: postgis_uses_stats(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_uses_stats() RETURNS boolean | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_uses_stats'; | |
ALTER FUNCTION public.postgis_uses_stats() OWNER TO postgres; | |
-- | |
-- TOC entry 372 (class 1255 OID 18726) | |
-- Dependencies: 6 | |
-- Name: postgis_version(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION postgis_version() RETURNS text | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'postgis_version'; | |
ALTER FUNCTION public.postgis_version() OWNER TO postgres; | |
-- | |
-- TOC entry 373 (class 1255 OID 18727) | |
-- Dependencies: 6 1170 | |
-- Name: probe_geometry_columns(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION probe_geometry_columns() RETURNS text | |
LANGUAGE plpgsql | |
AS $$ | |
DECLARE | |
inserted integer; | |
oldcount integer; | |
probed integer; | |
stale integer; | |
BEGIN | |
SELECT count(*) INTO oldcount FROM geometry_columns; | |
SELECT count(*) INTO probed | |
FROM pg_class c, pg_attribute a, pg_type t, | |
pg_namespace n, | |
pg_constraint sridcheck, pg_constraint typecheck | |
WHERE t.typname = 'geometry' | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
AND sridcheck.connamespace = n.oid | |
AND typecheck.connamespace = n.oid | |
AND sridcheck.conrelid = c.oid | |
AND sridcheck.consrc LIKE '(srid('||a.attname||') = %)' | |
AND typecheck.conrelid = c.oid | |
AND typecheck.consrc LIKE | |
'((geometrytype('||a.attname||') = ''%''::text) OR (% IS NULL))' | |
; | |
INSERT INTO geometry_columns SELECT | |
''::varchar as f_table_catalogue, | |
n.nspname::varchar as f_table_schema, | |
c.relname::varchar as f_table_name, | |
a.attname::varchar as f_geometry_column, | |
2 as coord_dimension, | |
trim(both ' =)' from | |
replace(replace(split_part( | |
sridcheck.consrc, ' = ', 2), ')', ''), '(', ''))::integer AS srid, | |
trim(both ' =)''' from substr(typecheck.consrc, | |
strpos(typecheck.consrc, '='), | |
strpos(typecheck.consrc, '::')- | |
strpos(typecheck.consrc, '=') | |
))::varchar as type | |
FROM pg_class c, pg_attribute a, pg_type t, | |
pg_namespace n, | |
pg_constraint sridcheck, pg_constraint typecheck | |
WHERE t.typname = 'geometry' | |
AND a.atttypid = t.oid | |
AND a.attrelid = c.oid | |
AND c.relnamespace = n.oid | |
AND sridcheck.connamespace = n.oid | |
AND typecheck.connamespace = n.oid | |
AND sridcheck.conrelid = c.oid | |
AND sridcheck.consrc LIKE '(st_srid('||a.attname||') = %)' | |
AND typecheck.conrelid = c.oid | |
AND typecheck.consrc LIKE | |
'((geometrytype('||a.attname||') = ''%''::text) OR (% IS NULL))' | |
AND NOT EXISTS ( | |
SELECT oid FROM geometry_columns gc | |
WHERE c.relname::varchar = gc.f_table_name | |
AND n.nspname::varchar = gc.f_table_schema | |
AND a.attname::varchar = gc.f_geometry_column | |
); | |
GET DIAGNOSTICS inserted = ROW_COUNT; | |
IF oldcount > probed THEN | |
stale = oldcount-probed; | |
ELSE | |
stale = 0; | |
END IF; | |
RETURN 'probed:'||probed::text|| | |
' inserted:'||inserted::text|| | |
' conflicts:'||(probed-inserted)::text|| | |
' stale:'||stale::text; | |
END | |
$$; | |
ALTER FUNCTION public.probe_geometry_columns() OWNER TO postgres; | |
-- | |
-- TOC entry 374 (class 1255 OID 18728) | |
-- Dependencies: 1102 6 1102 | |
-- Name: relate(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION relate(geometry, geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'relate_full'; | |
ALTER FUNCTION public.relate(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 375 (class 1255 OID 18729) | |
-- Dependencies: 1102 6 1102 | |
-- Name: relate(geometry, geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION relate(geometry, geometry, text) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'relate_pattern'; | |
ALTER FUNCTION public.relate(geometry, geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 376 (class 1255 OID 18730) | |
-- Dependencies: 6 1102 1102 | |
-- Name: removepoint(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION removepoint(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_removepoint'; | |
ALTER FUNCTION public.removepoint(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 377 (class 1255 OID 18731) | |
-- Dependencies: 6 | |
-- Name: rename_geometry_table_constraints(); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION rename_geometry_table_constraints() RETURNS text | |
LANGUAGE sql IMMUTABLE | |
AS $$ | |
SELECT 'rename_geometry_table_constraint() is obsoleted'::text | |
$$; | |
ALTER FUNCTION public.rename_geometry_table_constraints() OWNER TO postgres; | |
-- | |
-- TOC entry 378 (class 1255 OID 18732) | |
-- Dependencies: 6 1102 1102 | |
-- Name: reverse(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION reverse(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_reverse'; | |
ALTER FUNCTION public.reverse(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 379 (class 1255 OID 18733) | |
-- Dependencies: 1102 6 1102 | |
-- Name: rotate(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION rotate(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT rotateZ($1, $2)$_$; | |
ALTER FUNCTION public.rotate(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 380 (class 1255 OID 18734) | |
-- Dependencies: 1102 1102 6 | |
-- Name: rotatex(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION rotatex(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, 1, 0, 0, 0, cos($2), -sin($2), 0, sin($2), cos($2), 0, 0, 0)$_$; | |
ALTER FUNCTION public.rotatex(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 381 (class 1255 OID 18735) | |
-- Dependencies: 1102 1102 6 | |
-- Name: rotatey(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION rotatey(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, cos($2), 0, sin($2), 0, 1, 0, -sin($2), 0, cos($2), 0, 0, 0)$_$; | |
ALTER FUNCTION public.rotatey(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 382 (class 1255 OID 18736) | |
-- Dependencies: 1102 6 1102 | |
-- Name: rotatez(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION rotatez(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, cos($2), -sin($2), 0, sin($2), cos($2), 0, 0, 0, 1, 0, 0, 0)$_$; | |
ALTER FUNCTION public.rotatez(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 384 (class 1255 OID 18738) | |
-- Dependencies: 1102 6 1102 | |
-- Name: scale(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION scale(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT scale($1, $2, $3, 1)$_$; | |
ALTER FUNCTION public.scale(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 383 (class 1255 OID 18737) | |
-- Dependencies: 6 1102 1102 | |
-- Name: scale(geometry, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION scale(geometry, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, $2, 0, 0, 0, $3, 0, 0, 0, $4, 0, 0, 0)$_$; | |
ALTER FUNCTION public.scale(geometry, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 385 (class 1255 OID 18739) | |
-- Dependencies: 6 1102 1102 | |
-- Name: se_envelopesintersect(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_envelopesintersect(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT $1 && $2 | |
$_$; | |
ALTER FUNCTION public.se_envelopesintersect(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 386 (class 1255 OID 18740) | |
-- Dependencies: 6 1102 | |
-- Name: se_is3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_is3d(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_hasz'; | |
ALTER FUNCTION public.se_is3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 387 (class 1255 OID 18741) | |
-- Dependencies: 1102 6 | |
-- Name: se_ismeasured(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_ismeasured(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_hasm'; | |
ALTER FUNCTION public.se_ismeasured(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 388 (class 1255 OID 18742) | |
-- Dependencies: 1102 1102 6 | |
-- Name: se_locatealong(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_locatealong(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT locate_between_measures($1, $2, $2) $_$; | |
ALTER FUNCTION public.se_locatealong(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 389 (class 1255 OID 18743) | |
-- Dependencies: 1102 1102 6 | |
-- Name: se_locatebetween(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_locatebetween(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_locate_between_m'; | |
ALTER FUNCTION public.se_locatebetween(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 390 (class 1255 OID 18744) | |
-- Dependencies: 1102 6 | |
-- Name: se_m(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_m(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_m_point'; | |
ALTER FUNCTION public.se_m(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 391 (class 1255 OID 18745) | |
-- Dependencies: 1102 6 | |
-- Name: se_z(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION se_z(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_z_point'; | |
ALTER FUNCTION public.se_z(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 392 (class 1255 OID 18746) | |
-- Dependencies: 1102 6 1102 | |
-- Name: segmentize(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION segmentize(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_segmentize2d'; | |
ALTER FUNCTION public.segmentize(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 393 (class 1255 OID 18747) | |
-- Dependencies: 1096 1096 6 | |
-- Name: setfactor(chip, real); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION setfactor(chip, real) RETURNS chip | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_setFactor'; | |
ALTER FUNCTION public.setfactor(chip, real) OWNER TO postgres; | |
-- | |
-- TOC entry 394 (class 1255 OID 18748) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: setpoint(geometry, integer, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION setpoint(geometry, integer, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_setpoint_linestring'; | |
ALTER FUNCTION public.setpoint(geometry, integer, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 395 (class 1255 OID 18749) | |
-- Dependencies: 1096 6 1096 | |
-- Name: setsrid(chip, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION setsrid(chip, integer) RETURNS chip | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_setSRID'; | |
ALTER FUNCTION public.setsrid(chip, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 396 (class 1255 OID 18750) | |
-- Dependencies: 6 1102 1102 | |
-- Name: setsrid(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION setsrid(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_setSRID'; | |
ALTER FUNCTION public.setsrid(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 397 (class 1255 OID 18751) | |
-- Dependencies: 1102 6 1102 | |
-- Name: shift_longitude(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION shift_longitude(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_longitude_shift'; | |
ALTER FUNCTION public.shift_longitude(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 398 (class 1255 OID 18752) | |
-- Dependencies: 1102 1102 6 | |
-- Name: simplify(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION simplify(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_simplify2d'; | |
ALTER FUNCTION public.simplify(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 401 (class 1255 OID 18755) | |
-- Dependencies: 6 1102 1102 | |
-- Name: snaptogrid(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION snaptogrid(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT SnapToGrid($1, 0, 0, $2, $2)$_$; | |
ALTER FUNCTION public.snaptogrid(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 400 (class 1255 OID 18754) | |
-- Dependencies: 1102 6 1102 | |
-- Name: snaptogrid(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION snaptogrid(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT SnapToGrid($1, 0, 0, $2, $3)$_$; | |
ALTER FUNCTION public.snaptogrid(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 399 (class 1255 OID 18753) | |
-- Dependencies: 1102 6 1102 | |
-- Name: snaptogrid(geometry, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION snaptogrid(geometry, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_snaptogrid'; | |
ALTER FUNCTION public.snaptogrid(geometry, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 402 (class 1255 OID 18756) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: snaptogrid(geometry, geometry, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION snaptogrid(geometry, geometry, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_snaptogrid_pointoff'; | |
ALTER FUNCTION public.snaptogrid(geometry, geometry, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 403 (class 1255 OID 18757) | |
-- Dependencies: 6 1096 | |
-- Name: srid(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION srid(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getSRID'; | |
ALTER FUNCTION public.srid(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 404 (class 1255 OID 18758) | |
-- Dependencies: 6 1102 | |
-- Name: srid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION srid(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_getSRID'; | |
ALTER FUNCTION public.srid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 405 (class 1255 OID 18759) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_addmeasure(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_addmeasure(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ST_AddMeasure'; | |
ALTER FUNCTION public.st_addmeasure(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 406 (class 1255 OID 18760) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: st_addpoint(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_addpoint(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_addpoint'; | |
ALTER FUNCTION public.st_addpoint(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 407 (class 1255 OID 18761) | |
-- Dependencies: 1102 6 1102 1102 | |
-- Name: st_addpoint(geometry, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_addpoint(geometry, geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_addpoint'; | |
ALTER FUNCTION public.st_addpoint(geometry, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 409 (class 1255 OID 18763) | |
-- Dependencies: 1102 6 1102 | |
-- Name: st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, $2, $3, 0, $4, $5, 0, 0, 0, 1, $6, $7, 0)$_$; | |
ALTER FUNCTION public.st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 408 (class 1255 OID 18762) | |
-- Dependencies: 1102 6 1102 | |
-- Name: st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_affine'; | |
ALTER FUNCTION public.st_affine(geometry, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 410 (class 1255 OID 18764) | |
-- Dependencies: 1102 6 | |
-- Name: st_area(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_area(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_area_polygon'; | |
ALTER FUNCTION public.st_area(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 412 (class 1255 OID 18766) | |
-- Dependencies: 6 1099 | |
-- Name: st_area(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_area(geography) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_Area($1, true)$_$; | |
ALTER FUNCTION public.st_area(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 413 (class 1255 OID 18767) | |
-- Dependencies: 6 | |
-- Name: st_area(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_area(text) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Area($1::geometry); $_$; | |
ALTER FUNCTION public.st_area(text) OWNER TO postgres; | |
-- | |
-- TOC entry 411 (class 1255 OID 18765) | |
-- Dependencies: 6 1099 | |
-- Name: st_area(geography, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_area(geography, boolean) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'geography_area'; | |
ALTER FUNCTION public.st_area(geography, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 414 (class 1255 OID 18768) | |
-- Dependencies: 6 1102 | |
-- Name: st_area2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_area2d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_area_polygon'; | |
ALTER FUNCTION public.st_area2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 415 (class 1255 OID 18769) | |
-- Dependencies: 6 1102 | |
-- Name: st_asbinary(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asbinary(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asBinary'; | |
ALTER FUNCTION public.st_asbinary(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 417 (class 1255 OID 18771) | |
-- Dependencies: 1099 6 | |
-- Name: st_asbinary(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asbinary(geography) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_binary'; | |
ALTER FUNCTION public.st_asbinary(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 418 (class 1255 OID 18772) | |
-- Dependencies: 6 | |
-- Name: st_asbinary(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asbinary(text) RETURNS bytea | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_AsBinary($1::geometry); $_$; | |
ALTER FUNCTION public.st_asbinary(text) OWNER TO postgres; | |
-- | |
-- TOC entry 416 (class 1255 OID 18770) | |
-- Dependencies: 6 1102 | |
-- Name: st_asbinary(geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asbinary(geometry, text) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asBinary'; | |
ALTER FUNCTION public.st_asbinary(geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 419 (class 1255 OID 18773) | |
-- Dependencies: 6 1102 | |
-- Name: st_asewkb(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asewkb(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'WKBFromLWGEOM'; | |
ALTER FUNCTION public.st_asewkb(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 420 (class 1255 OID 18774) | |
-- Dependencies: 6 1102 | |
-- Name: st_asewkb(geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asewkb(geometry, text) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'WKBFromLWGEOM'; | |
ALTER FUNCTION public.st_asewkb(geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 421 (class 1255 OID 18775) | |
-- Dependencies: 1102 6 | |
-- Name: st_asewkt(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asewkt(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asEWKT'; | |
ALTER FUNCTION public.st_asewkt(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 423 (class 1255 OID 18777) | |
-- Dependencies: 1102 6 | |
-- Name: st_asgeojson(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson(1, $1, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 429 (class 1255 OID 18783) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgeojson(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(geography) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson(1, $1, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 430 (class 1255 OID 18784) | |
-- Dependencies: 6 | |
-- Name: st_asgeojson(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(text) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_AsGeoJson($1::geometry); $_$; | |
ALTER FUNCTION public.st_asgeojson(text) OWNER TO postgres; | |
-- | |
-- TOC entry 422 (class 1255 OID 18776) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgeojson(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson(1, $1, $2, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 424 (class 1255 OID 18778) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgeojson(integer, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(integer, geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson($1, $2, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(integer, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 428 (class 1255 OID 18782) | |
-- Dependencies: 1099 6 | |
-- Name: st_asgeojson(geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(geography, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson(1, $1, $2, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 431 (class 1255 OID 18785) | |
-- Dependencies: 1099 6 | |
-- Name: st_asgeojson(integer, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(integer, geography) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson($1, $2, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(integer, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 425 (class 1255 OID 18779) | |
-- Dependencies: 1102 6 | |
-- Name: st_asgeojson(integer, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(integer, geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson($1, $2, $3, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(integer, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 426 (class 1255 OID 18780) | |
-- Dependencies: 1102 6 | |
-- Name: st_asgeojson(geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(geometry, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson(1, $1, $2, $3)$_$; | |
ALTER FUNCTION public.st_asgeojson(geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 432 (class 1255 OID 18786) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgeojson(integer, geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(integer, geography, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson($1, $2, $3, 0)$_$; | |
ALTER FUNCTION public.st_asgeojson(integer, geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 433 (class 1255 OID 18787) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgeojson(geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(geography, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson(1, $1, $2, $3)$_$; | |
ALTER FUNCTION public.st_asgeojson(geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 427 (class 1255 OID 18781) | |
-- Dependencies: 1102 6 | |
-- Name: st_asgeojson(integer, geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(integer, geometry, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson($1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.st_asgeojson(integer, geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 434 (class 1255 OID 18788) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgeojson(integer, geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgeojson(integer, geography, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGeoJson($1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.st_asgeojson(integer, geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 436 (class 1255 OID 18790) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgml(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgml(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 442 (class 1255 OID 18796) | |
-- Dependencies: 1099 6 | |
-- Name: st_asgml(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(geography) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgml(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 443 (class 1255 OID 18797) | |
-- Dependencies: 6 | |
-- Name: st_asgml(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(text) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_AsGML($1::geometry); $_$; | |
ALTER FUNCTION public.st_asgml(text) OWNER TO postgres; | |
-- | |
-- TOC entry 435 (class 1255 OID 18789) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgml(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, $2, 0)$_$; | |
ALTER FUNCTION public.st_asgml(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 437 (class 1255 OID 18791) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgml(integer, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(integer, geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML($1, $2, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgml(integer, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 441 (class 1255 OID 18795) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgml(geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(geography, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, $2, 0)$_$; | |
ALTER FUNCTION public.st_asgml(geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 444 (class 1255 OID 18798) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgml(integer, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(integer, geography) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML($1, $2, 15, 0)$_$; | |
ALTER FUNCTION public.st_asgml(integer, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 438 (class 1255 OID 18792) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgml(integer, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(integer, geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML($1, $2, $3, 0)$_$; | |
ALTER FUNCTION public.st_asgml(integer, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 439 (class 1255 OID 18793) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgml(geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(geometry, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, $2, $3)$_$; | |
ALTER FUNCTION public.st_asgml(geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 445 (class 1255 OID 18799) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgml(integer, geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(integer, geography, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML($1, $2, $3, 0)$_$; | |
ALTER FUNCTION public.st_asgml(integer, geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 446 (class 1255 OID 18800) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgml(geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(geography, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML(2, $1, $2, $3)$_$; | |
ALTER FUNCTION public.st_asgml(geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 440 (class 1255 OID 18794) | |
-- Dependencies: 6 1102 | |
-- Name: st_asgml(integer, geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(integer, geometry, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML($1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.st_asgml(integer, geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 447 (class 1255 OID 18801) | |
-- Dependencies: 6 1099 | |
-- Name: st_asgml(integer, geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_asgml(integer, geography, integer, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsGML($1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.st_asgml(integer, geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 448 (class 1255 OID 18802) | |
-- Dependencies: 6 1102 | |
-- Name: st_ashexewkb(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_ashexewkb(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asHEXEWKB'; | |
ALTER FUNCTION public.st_ashexewkb(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 449 (class 1255 OID 18803) | |
-- Dependencies: 6 1102 | |
-- Name: st_ashexewkb(geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_ashexewkb(geometry, text) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asHEXEWKB'; | |
ALTER FUNCTION public.st_ashexewkb(geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 451 (class 1255 OID 18805) | |
-- Dependencies: 6 1102 | |
-- Name: st_askml(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML(2, ST_Transform($1,4326), 15)$_$; | |
ALTER FUNCTION public.st_askml(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 455 (class 1255 OID 18809) | |
-- Dependencies: 6 1099 | |
-- Name: st_askml(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(geography) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML(2, $1, 15)$_$; | |
ALTER FUNCTION public.st_askml(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 456 (class 1255 OID 18810) | |
-- Dependencies: 6 | |
-- Name: st_askml(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(text) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_AsKML($1::geometry); $_$; | |
ALTER FUNCTION public.st_askml(text) OWNER TO postgres; | |
-- | |
-- TOC entry 450 (class 1255 OID 18804) | |
-- Dependencies: 6 1102 | |
-- Name: st_askml(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML(2, ST_Transform($1,4326), $2)$_$; | |
ALTER FUNCTION public.st_askml(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 452 (class 1255 OID 18806) | |
-- Dependencies: 6 1102 | |
-- Name: st_askml(integer, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(integer, geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML($1, ST_Transform($2,4326), 15)$_$; | |
ALTER FUNCTION public.st_askml(integer, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 454 (class 1255 OID 18808) | |
-- Dependencies: 6 1099 | |
-- Name: st_askml(geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(geography, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML(2, $1, $2)$_$; | |
ALTER FUNCTION public.st_askml(geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 457 (class 1255 OID 18811) | |
-- Dependencies: 6 1099 | |
-- Name: st_askml(integer, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(integer, geography) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML($1, $2, 15)$_$; | |
ALTER FUNCTION public.st_askml(integer, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 453 (class 1255 OID 18807) | |
-- Dependencies: 6 1102 | |
-- Name: st_askml(integer, geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(integer, geometry, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML($1, ST_Transform($2,4326), $3)$_$; | |
ALTER FUNCTION public.st_askml(integer, geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 458 (class 1255 OID 18812) | |
-- Dependencies: 6 1099 | |
-- Name: st_askml(integer, geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_askml(integer, geography, integer) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_AsKML($1, $2, $3)$_$; | |
ALTER FUNCTION public.st_askml(integer, geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 461 (class 1255 OID 18815) | |
-- Dependencies: 6 1102 | |
-- Name: st_assvg(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'assvg_geometry'; | |
ALTER FUNCTION public.st_assvg(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 464 (class 1255 OID 18818) | |
-- Dependencies: 6 1099 | |
-- Name: st_assvg(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(geography) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_svg'; | |
ALTER FUNCTION public.st_assvg(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 465 (class 1255 OID 18819) | |
-- Dependencies: 6 | |
-- Name: st_assvg(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(text) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_AsSVG($1::geometry); $_$; | |
ALTER FUNCTION public.st_assvg(text) OWNER TO postgres; | |
-- | |
-- TOC entry 460 (class 1255 OID 18814) | |
-- Dependencies: 6 1102 | |
-- Name: st_assvg(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(geometry, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'assvg_geometry'; | |
ALTER FUNCTION public.st_assvg(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 463 (class 1255 OID 18817) | |
-- Dependencies: 6 1099 | |
-- Name: st_assvg(geography, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(geography, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_svg'; | |
ALTER FUNCTION public.st_assvg(geography, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 459 (class 1255 OID 18813) | |
-- Dependencies: 6 1102 | |
-- Name: st_assvg(geometry, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(geometry, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'assvg_geometry'; | |
ALTER FUNCTION public.st_assvg(geometry, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 462 (class 1255 OID 18816) | |
-- Dependencies: 6 1099 | |
-- Name: st_assvg(geography, integer, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_assvg(geography, integer, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_svg'; | |
ALTER FUNCTION public.st_assvg(geography, integer, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 466 (class 1255 OID 18820) | |
-- Dependencies: 6 1102 | |
-- Name: st_astext(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_astext(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_asText'; | |
ALTER FUNCTION public.st_astext(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 467 (class 1255 OID 18821) | |
-- Dependencies: 6 1099 | |
-- Name: st_astext(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_astext(geography) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_as_text'; | |
ALTER FUNCTION public.st_astext(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 468 (class 1255 OID 18822) | |
-- Dependencies: 6 | |
-- Name: st_astext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_astext(text) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_AsText($1::geometry); $_$; | |
ALTER FUNCTION public.st_astext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 469 (class 1255 OID 18823) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_azimuth(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_azimuth(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_azimuth'; | |
ALTER FUNCTION public.st_azimuth(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 470 (class 1255 OID 18824) | |
-- Dependencies: 6 1170 1102 | |
-- Name: st_bdmpolyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_bdmpolyfromtext(text, integer) RETURNS geometry | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
geomtext alias for $1; | |
srid alias for $2; | |
mline geometry; | |
geom geometry; | |
BEGIN | |
mline := ST_MultiLineStringFromText(geomtext, srid); | |
IF mline IS NULL | |
THEN | |
RAISE EXCEPTION 'Input is not a MultiLinestring'; | |
END IF; | |
geom := multi(ST_BuildArea(mline)); | |
RETURN geom; | |
END; | |
$_$; | |
ALTER FUNCTION public.st_bdmpolyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 471 (class 1255 OID 18825) | |
-- Dependencies: 6 1170 1102 | |
-- Name: st_bdpolyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_bdpolyfromtext(text, integer) RETURNS geometry | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
geomtext alias for $1; | |
srid alias for $2; | |
mline geometry; | |
geom geometry; | |
BEGIN | |
mline := ST_MultiLineStringFromText(geomtext, srid); | |
IF mline IS NULL | |
THEN | |
RAISE EXCEPTION 'Input is not a MultiLinestring'; | |
END IF; | |
geom := ST_BuildArea(mline); | |
IF GeometryType(geom) != 'POLYGON' | |
THEN | |
RAISE EXCEPTION 'Input returns more then a single polygon, try using BdMPolyFromText instead'; | |
END IF; | |
RETURN geom; | |
END; | |
$_$; | |
ALTER FUNCTION public.st_bdpolyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 472 (class 1255 OID 18826) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_boundary(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_boundary(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'boundary'; | |
ALTER FUNCTION public.st_boundary(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 473 (class 1255 OID 18827) | |
-- Dependencies: 6 1102 | |
-- Name: st_box(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box(geometry) RETURNS box | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX'; | |
ALTER FUNCTION public.st_box(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 474 (class 1255 OID 18828) | |
-- Dependencies: 6 1090 | |
-- Name: st_box(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box(box3d) RETURNS box | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_BOX'; | |
ALTER FUNCTION public.st_box(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 475 (class 1255 OID 18829) | |
-- Dependencies: 6 1087 1102 | |
-- Name: st_box2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box2d(geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.st_box2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 476 (class 1255 OID 18830) | |
-- Dependencies: 6 1087 1090 | |
-- Name: st_box2d(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box2d(box3d) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.st_box2d(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 477 (class 1255 OID 18831) | |
-- Dependencies: 6 1087 1093 | |
-- Name: st_box2d(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box2d(box3d_extent) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_BOX2DFLOAT4'; | |
ALTER FUNCTION public.st_box2d(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 478 (class 1255 OID 18832) | |
-- Dependencies: 6 1087 | |
-- Name: st_box2d_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box2d_in(cstring) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_in'; | |
ALTER FUNCTION public.st_box2d_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 479 (class 1255 OID 18833) | |
-- Dependencies: 6 1087 | |
-- Name: st_box2d_out(box2d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box2d_out(box2d) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_out'; | |
ALTER FUNCTION public.st_box2d_out(box2d) OWNER TO postgres; | |
-- | |
-- TOC entry 480 (class 1255 OID 18834) | |
-- Dependencies: 6 1090 1102 | |
-- Name: st_box3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box3d(geometry) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_BOX3D'; | |
ALTER FUNCTION public.st_box3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 481 (class 1255 OID 18835) | |
-- Dependencies: 6 1090 1087 | |
-- Name: st_box3d(box2d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box3d(box2d) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_to_BOX3D'; | |
ALTER FUNCTION public.st_box3d(box2d) OWNER TO postgres; | |
-- | |
-- TOC entry 482 (class 1255 OID 18836) | |
-- Dependencies: 6 1090 1093 | |
-- Name: st_box3d_extent(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box3d_extent(box3d_extent) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_extent_to_BOX3D'; | |
ALTER FUNCTION public.st_box3d_extent(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 483 (class 1255 OID 18837) | |
-- Dependencies: 6 1090 | |
-- Name: st_box3d_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box3d_in(cstring) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_in'; | |
ALTER FUNCTION public.st_box3d_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 484 (class 1255 OID 18838) | |
-- Dependencies: 6 1090 | |
-- Name: st_box3d_out(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_box3d_out(box3d) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_out'; | |
ALTER FUNCTION public.st_box3d_out(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 485 (class 1255 OID 18839) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_buffer(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_buffer(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'buffer'; | |
ALTER FUNCTION public.st_buffer(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 488 (class 1255 OID 18842) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_buffer(geography, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_buffer(geography, double precision) RETURNS geography | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT geography(ST_Transform(ST_Buffer(ST_Transform(geometry($1), _ST_BestSRID($1)), $2), 4326))$_$; | |
ALTER FUNCTION public.st_buffer(geography, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 489 (class 1255 OID 18843) | |
-- Dependencies: 6 1102 | |
-- Name: st_buffer(text, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_buffer(text, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Buffer($1::geometry, $2); $_$; | |
ALTER FUNCTION public.st_buffer(text, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 486 (class 1255 OID 18840) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_buffer(geometry, double precision, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_buffer(geometry, double precision, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT _ST_Buffer($1, $2, | |
CAST('quad_segs='||CAST($3 AS text) as cstring)) | |
$_$; | |
ALTER FUNCTION public.st_buffer(geometry, double precision, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 487 (class 1255 OID 18841) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_buffer(geometry, double precision, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_buffer(geometry, double precision, text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT _ST_Buffer($1, $2, | |
CAST( regexp_replace($3, '^[0123456789]+$', | |
'quad_segs='||$3) AS cstring) | |
) | |
$_$; | |
ALTER FUNCTION public.st_buffer(geometry, double precision, text) OWNER TO postgres; | |
-- | |
-- TOC entry 490 (class 1255 OID 18844) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_buildarea(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_buildarea(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_buildarea'; | |
ALTER FUNCTION public.st_buildarea(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 491 (class 1255 OID 18845) | |
-- Dependencies: 6 1102 | |
-- Name: st_bytea(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_bytea(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_bytea'; | |
ALTER FUNCTION public.st_bytea(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 492 (class 1255 OID 18846) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_centroid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_centroid(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'centroid'; | |
ALTER FUNCTION public.st_centroid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 493 (class 1255 OID 18847) | |
-- Dependencies: 6 1096 | |
-- Name: st_chip_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_chip_in(cstring) RETURNS chip | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_in'; | |
ALTER FUNCTION public.st_chip_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 494 (class 1255 OID 18848) | |
-- Dependencies: 6 1096 | |
-- Name: st_chip_out(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_chip_out(chip) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_out'; | |
ALTER FUNCTION public.st_chip_out(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 495 (class 1255 OID 18849) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_closestpoint(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_closestpoint(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_closestpoint'; | |
ALTER FUNCTION public.st_closestpoint(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 497 (class 1255 OID 18851) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_collect(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_collect(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_collect_garray'; | |
ALTER FUNCTION public.st_collect(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 496 (class 1255 OID 18850) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_collect(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_collect(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'LWGEOM_collect'; | |
ALTER FUNCTION public.st_collect(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 498 (class 1255 OID 18852) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_collectionextract(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_collectionextract(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ST_CollectionExtract'; | |
ALTER FUNCTION public.st_collectionextract(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 499 (class 1255 OID 18853) | |
-- Dependencies: 6 1087 1087 1102 | |
-- Name: st_combine_bbox(box2d, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_combine_bbox(box2d, geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_combine'; | |
ALTER FUNCTION public.st_combine_bbox(box2d, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 500 (class 1255 OID 18854) | |
-- Dependencies: 6 1093 1093 1102 | |
-- Name: st_combine_bbox(box3d_extent, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_combine_bbox(box3d_extent, geometry) RETURNS box3d_extent | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'BOX3D_combine'; | |
ALTER FUNCTION public.st_combine_bbox(box3d_extent, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 501 (class 1255 OID 18855) | |
-- Dependencies: 6 1090 1090 1102 | |
-- Name: st_combine_bbox(box3d, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_combine_bbox(box3d, geometry) RETURNS box3d | |
LANGUAGE c IMMUTABLE | |
AS '$libdir/postgis-1.5', 'BOX3D_combine'; | |
ALTER FUNCTION public.st_combine_bbox(box3d, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 502 (class 1255 OID 18856) | |
-- Dependencies: 6 1096 | |
-- Name: st_compression(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_compression(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getCompression'; | |
ALTER FUNCTION public.st_compression(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 503 (class 1255 OID 18857) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_contains(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_contains(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Contains($1,$2)$_$; | |
ALTER FUNCTION public.st_contains(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 504 (class 1255 OID 18858) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_containsproperly(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_containsproperly(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_ContainsProperly($1,$2)$_$; | |
ALTER FUNCTION public.st_containsproperly(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 505 (class 1255 OID 18859) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_convexhull(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_convexhull(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'convexhull'; | |
ALTER FUNCTION public.st_convexhull(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 506 (class 1255 OID 18860) | |
-- Dependencies: 6 1102 | |
-- Name: st_coorddim(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_coorddim(geometry) RETURNS smallint | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_ndims'; | |
ALTER FUNCTION public.st_coorddim(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 507 (class 1255 OID 18861) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_coveredby(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_coveredby(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_CoveredBy($1,$2)$_$; | |
ALTER FUNCTION public.st_coveredby(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 508 (class 1255 OID 18862) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_coveredby(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_coveredby(geography, geography) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT $1 && $2 AND _ST_Covers($2, $1)$_$; | |
ALTER FUNCTION public.st_coveredby(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 509 (class 1255 OID 18863) | |
-- Dependencies: 6 | |
-- Name: st_coveredby(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_coveredby(text, text) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_CoveredBy($1::geometry, $2::geometry); $_$; | |
ALTER FUNCTION public.st_coveredby(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 510 (class 1255 OID 18864) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_covers(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_covers(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Covers($1,$2)$_$; | |
ALTER FUNCTION public.st_covers(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 511 (class 1255 OID 18865) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_covers(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_covers(geography, geography) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT $1 && $2 AND _ST_Covers($1, $2)$_$; | |
ALTER FUNCTION public.st_covers(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 512 (class 1255 OID 18866) | |
-- Dependencies: 6 | |
-- Name: st_covers(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_covers(text, text) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Covers($1::geometry, $2::geometry); $_$; | |
ALTER FUNCTION public.st_covers(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 513 (class 1255 OID 18867) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_crosses(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_crosses(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Crosses($1,$2)$_$; | |
ALTER FUNCTION public.st_crosses(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 515 (class 1255 OID 18869) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_curvetoline(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_curvetoline(geometry) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_CurveToLine($1, 32)$_$; | |
ALTER FUNCTION public.st_curvetoline(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 514 (class 1255 OID 18868) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_curvetoline(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_curvetoline(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_curve_segmentize'; | |
ALTER FUNCTION public.st_curvetoline(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 516 (class 1255 OID 18870) | |
-- Dependencies: 6 1096 | |
-- Name: st_datatype(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_datatype(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getDatatype'; | |
ALTER FUNCTION public.st_datatype(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 517 (class 1255 OID 18871) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_dfullywithin(geometry, geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dfullywithin(geometry, geometry, double precision) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && ST_Expand($2,$3) AND $2 && ST_Expand($1,$3) AND _ST_DFullyWithin(ST_ConvexHull($1), ST_ConvexHull($2), $3)$_$; | |
ALTER FUNCTION public.st_dfullywithin(geometry, geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 518 (class 1255 OID 18872) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_difference(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_difference(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'difference'; | |
ALTER FUNCTION public.st_difference(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 519 (class 1255 OID 18873) | |
-- Dependencies: 6 1102 | |
-- Name: st_dimension(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dimension(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dimension'; | |
ALTER FUNCTION public.st_dimension(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 520 (class 1255 OID 18874) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_disjoint(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_disjoint(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'disjoint'; | |
ALTER FUNCTION public.st_disjoint(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 521 (class 1255 OID 18875) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_distance(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_distance(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_mindistance2d'; | |
ALTER FUNCTION public.st_distance(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 523 (class 1255 OID 18877) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_distance(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_distance(geography, geography) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_Distance($1, $2, 0.0, true)$_$; | |
ALTER FUNCTION public.st_distance(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 524 (class 1255 OID 18878) | |
-- Dependencies: 6 | |
-- Name: st_distance(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_distance(text, text) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Distance($1::geometry, $2::geometry); $_$; | |
ALTER FUNCTION public.st_distance(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 522 (class 1255 OID 18876) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_distance(geography, geography, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_distance(geography, geography, boolean) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_Distance($1, $2, 0.0, $3)$_$; | |
ALTER FUNCTION public.st_distance(geography, geography, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 525 (class 1255 OID 18879) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_distance_sphere(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_distance_sphere(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_distance_sphere'; | |
ALTER FUNCTION public.st_distance_sphere(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 526 (class 1255 OID 18880) | |
-- Dependencies: 6 1102 1102 1113 | |
-- Name: st_distance_spheroid(geometry, geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_distance_spheroid(geometry, geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_distance_ellipsoid'; | |
ALTER FUNCTION public.st_distance_spheroid(geometry, geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 527 (class 1255 OID 18881) | |
-- Dependencies: 6 1105 1102 | |
-- Name: st_dump(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dump(geometry) RETURNS SETOF geometry_dump | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dump'; | |
ALTER FUNCTION public.st_dump(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 528 (class 1255 OID 18882) | |
-- Dependencies: 6 1105 1102 | |
-- Name: st_dumppoints(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dumppoints(geometry) RETURNS SETOF geometry_dump | |
LANGUAGE sql | |
AS $_$ | |
SELECT * FROM _ST_DumpPoints($1, NULL); | |
$_$; | |
ALTER FUNCTION public.st_dumppoints(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 529 (class 1255 OID 18883) | |
-- Dependencies: 6 1105 1102 | |
-- Name: st_dumprings(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dumprings(geometry) RETURNS SETOF geometry_dump | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_dump_rings'; | |
ALTER FUNCTION public.st_dumprings(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 530 (class 1255 OID 18884) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_dwithin(geometry, geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dwithin(geometry, geometry, double precision) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && ST_Expand($2,$3) AND $2 && ST_Expand($1,$3) AND _ST_DWithin($1, $2, $3)$_$; | |
ALTER FUNCTION public.st_dwithin(geometry, geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 532 (class 1255 OID 18886) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_dwithin(geography, geography, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dwithin(geography, geography, double precision) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && _ST_Expand($2,$3) AND $2 && _ST_Expand($1,$3) AND _ST_DWithin($1, $2, $3, true)$_$; | |
ALTER FUNCTION public.st_dwithin(geography, geography, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 533 (class 1255 OID 18887) | |
-- Dependencies: 6 | |
-- Name: st_dwithin(text, text, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dwithin(text, text, double precision) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_DWithin($1::geometry, $2::geometry, $3); $_$; | |
ALTER FUNCTION public.st_dwithin(text, text, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 531 (class 1255 OID 18885) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_dwithin(geography, geography, double precision, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_dwithin(geography, geography, double precision, boolean) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && _ST_Expand($2,$3) AND $2 && _ST_Expand($1,$3) AND _ST_DWithin($1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.st_dwithin(geography, geography, double precision, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 534 (class 1255 OID 18888) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_endpoint(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_endpoint(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_endpoint_linestring'; | |
ALTER FUNCTION public.st_endpoint(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 535 (class 1255 OID 18889) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_envelope(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_envelope(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_envelope'; | |
ALTER FUNCTION public.st_envelope(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 536 (class 1255 OID 18890) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_equals(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_equals(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT $1 && $2 AND _ST_Equals($1,$2)$_$; | |
ALTER FUNCTION public.st_equals(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 538 (class 1255 OID 18892) | |
-- Dependencies: 6 1087 | |
-- Name: st_estimated_extent(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_estimated_extent(text, text) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT SECURITY DEFINER | |
AS '$libdir/postgis-1.5', 'LWGEOM_estimated_extent'; | |
ALTER FUNCTION public.st_estimated_extent(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 537 (class 1255 OID 18891) | |
-- Dependencies: 6 1087 | |
-- Name: st_estimated_extent(text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_estimated_extent(text, text, text) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT SECURITY DEFINER | |
AS '$libdir/postgis-1.5', 'LWGEOM_estimated_extent'; | |
ALTER FUNCTION public.st_estimated_extent(text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 539 (class 1255 OID 18893) | |
-- Dependencies: 6 1090 1090 | |
-- Name: st_expand(box3d, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_expand(box3d, double precision) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_expand'; | |
ALTER FUNCTION public.st_expand(box3d, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 540 (class 1255 OID 18896) | |
-- Dependencies: 6 1087 1087 | |
-- Name: st_expand(box2d, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_expand(box2d, double precision) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_expand'; | |
ALTER FUNCTION public.st_expand(box2d, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 541 (class 1255 OID 18897) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_expand(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_expand(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_expand'; | |
ALTER FUNCTION public.st_expand(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 542 (class 1255 OID 18898) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_exteriorring(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_exteriorring(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_exteriorring_polygon'; | |
ALTER FUNCTION public.st_exteriorring(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 543 (class 1255 OID 18899) | |
-- Dependencies: 6 1096 | |
-- Name: st_factor(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_factor(chip) RETURNS real | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getFactor'; | |
ALTER FUNCTION public.st_factor(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 545 (class 1255 OID 18901) | |
-- Dependencies: 6 1170 1087 | |
-- Name: st_find_extent(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_find_extent(text, text) RETURNS box2d | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
tablename alias for $1; | |
columnname alias for $2; | |
myrec RECORD; | |
BEGIN | |
FOR myrec IN EXECUTE 'SELECT extent("' || columnname || '") FROM "' || tablename || '"' LOOP | |
return myrec.extent; | |
END LOOP; | |
END; | |
$_$; | |
ALTER FUNCTION public.st_find_extent(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 544 (class 1255 OID 18900) | |
-- Dependencies: 6 1170 1087 | |
-- Name: st_find_extent(text, text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_find_extent(text, text, text) RETURNS box2d | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $_$ | |
DECLARE | |
schemaname alias for $1; | |
tablename alias for $2; | |
columnname alias for $3; | |
myrec RECORD; | |
BEGIN | |
FOR myrec IN EXECUTE 'SELECT extent("' || columnname || '") FROM "' || schemaname || '"."' || tablename || '"' LOOP | |
return myrec.extent; | |
END LOOP; | |
END; | |
$_$; | |
ALTER FUNCTION public.st_find_extent(text, text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 546 (class 1255 OID 18902) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_force_2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_force_2d(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_2d'; | |
ALTER FUNCTION public.st_force_2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 547 (class 1255 OID 18903) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_force_3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_force_3d(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_3dz'; | |
ALTER FUNCTION public.st_force_3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 548 (class 1255 OID 18904) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_force_3dm(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_force_3dm(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_3dm'; | |
ALTER FUNCTION public.st_force_3dm(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 549 (class 1255 OID 18905) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_force_3dz(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_force_3dz(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_3dz'; | |
ALTER FUNCTION public.st_force_3dz(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 550 (class 1255 OID 18906) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_force_4d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_force_4d(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_4d'; | |
ALTER FUNCTION public.st_force_4d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 551 (class 1255 OID 18907) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_force_collection(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_force_collection(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_collection'; | |
ALTER FUNCTION public.st_force_collection(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 552 (class 1255 OID 18908) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_forcerhr(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_forcerhr(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_forceRHR_poly'; | |
ALTER FUNCTION public.st_forcerhr(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 553 (class 1255 OID 18909) | |
-- Dependencies: 6 1099 | |
-- Name: st_geogfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geogfromtext(text) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_from_text'; | |
ALTER FUNCTION public.st_geogfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 554 (class 1255 OID 18910) | |
-- Dependencies: 6 1099 | |
-- Name: st_geogfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geogfromwkb(bytea) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_from_binary'; | |
ALTER FUNCTION public.st_geogfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 555 (class 1255 OID 18911) | |
-- Dependencies: 6 1099 | |
-- Name: st_geographyfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geographyfromtext(text) RETURNS geography | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geography_from_text'; | |
ALTER FUNCTION public.st_geographyfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 557 (class 1255 OID 18913) | |
-- Dependencies: 6 1102 | |
-- Name: st_geohash(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geohash(geometry) RETURNS text | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_GeoHash($1, 0)$_$; | |
ALTER FUNCTION public.st_geohash(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 556 (class 1255 OID 18912) | |
-- Dependencies: 6 1102 | |
-- Name: st_geohash(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geohash(geometry, integer) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ST_GeoHash'; | |
ALTER FUNCTION public.st_geohash(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 559 (class 1255 OID 18915) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomcollfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomcollfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(ST_GeomFromText($1)) = 'GEOMETRYCOLLECTION' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_geomcollfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 558 (class 1255 OID 18914) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomcollfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomcollfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(ST_GeomFromText($1, $2)) = 'GEOMETRYCOLLECTION' | |
THEN ST_GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_geomcollfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 561 (class 1255 OID 18917) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomcollfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomcollfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(ST_GeomFromWKB($1)) = 'GEOMETRYCOLLECTION' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_geomcollfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 560 (class 1255 OID 18916) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomcollfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomcollfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromWKB($1, $2)) = 'GEOMETRYCOLLECTION' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_geomcollfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 562 (class 1255 OID 18918) | |
-- Dependencies: 6 1102 1087 | |
-- Name: st_geometry(box2d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry(box2d) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_to_LWGEOM'; | |
ALTER FUNCTION public.st_geometry(box2d) OWNER TO postgres; | |
-- | |
-- TOC entry 563 (class 1255 OID 18919) | |
-- Dependencies: 6 1102 1090 | |
-- Name: st_geometry(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry(box3d) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_LWGEOM'; | |
ALTER FUNCTION public.st_geometry(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 564 (class 1255 OID 18920) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometry(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'parse_WKT_lwgeom'; | |
ALTER FUNCTION public.st_geometry(text) OWNER TO postgres; | |
-- | |
-- TOC entry 565 (class 1255 OID 18921) | |
-- Dependencies: 6 1102 1096 | |
-- Name: st_geometry(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry(chip) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_to_LWGEOM'; | |
ALTER FUNCTION public.st_geometry(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 566 (class 1255 OID 18922) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometry(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_bytea'; | |
ALTER FUNCTION public.st_geometry(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 567 (class 1255 OID 18923) | |
-- Dependencies: 6 1102 1093 | |
-- Name: st_geometry(box3d_extent); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry(box3d_extent) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_to_LWGEOM'; | |
ALTER FUNCTION public.st_geometry(box3d_extent) OWNER TO postgres; | |
-- | |
-- TOC entry 568 (class 1255 OID 18924) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_above(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_above(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_above'; | |
ALTER FUNCTION public.st_geometry_above(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 569 (class 1255 OID 18925) | |
-- Dependencies: 6 | |
-- Name: st_geometry_analyze(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_analyze(internal) RETURNS boolean | |
LANGUAGE c STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_analyze'; | |
ALTER FUNCTION public.st_geometry_analyze(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 570 (class 1255 OID 18926) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_below(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_below(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_below'; | |
ALTER FUNCTION public.st_geometry_below(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 571 (class 1255 OID 18927) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_cmp(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_cmp(geometry, geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_cmp'; | |
ALTER FUNCTION public.st_geometry_cmp(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 572 (class 1255 OID 18928) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_contain(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_contain(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_contain'; | |
ALTER FUNCTION public.st_geometry_contain(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 573 (class 1255 OID 18929) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_contained(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_contained(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_contained'; | |
ALTER FUNCTION public.st_geometry_contained(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 574 (class 1255 OID 18930) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_eq(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_eq(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_eq'; | |
ALTER FUNCTION public.st_geometry_eq(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 575 (class 1255 OID 18931) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_ge(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_ge(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_ge'; | |
ALTER FUNCTION public.st_geometry_ge(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 576 (class 1255 OID 18932) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_gt(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_gt(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_gt'; | |
ALTER FUNCTION public.st_geometry_gt(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 577 (class 1255 OID 18933) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometry_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_in(cstring) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_in'; | |
ALTER FUNCTION public.st_geometry_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 578 (class 1255 OID 18934) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_le(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_le(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_le'; | |
ALTER FUNCTION public.st_geometry_le(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 579 (class 1255 OID 18935) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_left(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_left(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_left'; | |
ALTER FUNCTION public.st_geometry_left(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 580 (class 1255 OID 18936) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_lt(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_lt(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'lwgeom_lt'; | |
ALTER FUNCTION public.st_geometry_lt(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 581 (class 1255 OID 18937) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometry_out(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_out(geometry) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_out'; | |
ALTER FUNCTION public.st_geometry_out(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 582 (class 1255 OID 18938) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_overabove(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_overabove(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overabove'; | |
ALTER FUNCTION public.st_geometry_overabove(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 583 (class 1255 OID 18939) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_overbelow(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_overbelow(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overbelow'; | |
ALTER FUNCTION public.st_geometry_overbelow(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 584 (class 1255 OID 18940) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_overlap(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_overlap(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overlap'; | |
ALTER FUNCTION public.st_geometry_overlap(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 585 (class 1255 OID 18941) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_overleft(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_overleft(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overleft'; | |
ALTER FUNCTION public.st_geometry_overleft(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 586 (class 1255 OID 18942) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_overright(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_overright(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_overright'; | |
ALTER FUNCTION public.st_geometry_overright(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 587 (class 1255 OID 18943) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometry_recv(internal); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_recv(internal) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_recv'; | |
ALTER FUNCTION public.st_geometry_recv(internal) OWNER TO postgres; | |
-- | |
-- TOC entry 588 (class 1255 OID 18944) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_right(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_right(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_right'; | |
ALTER FUNCTION public.st_geometry_right(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 589 (class 1255 OID 18945) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometry_same(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_same(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_samebox'; | |
ALTER FUNCTION public.st_geometry_same(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 590 (class 1255 OID 18946) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometry_send(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometry_send(geometry) RETURNS bytea | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_send'; | |
ALTER FUNCTION public.st_geometry_send(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 591 (class 1255 OID 18947) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometryfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometryfromtext(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.st_geometryfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 592 (class 1255 OID 18948) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometryfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometryfromtext(text, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.st_geometryfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 593 (class 1255 OID 18949) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_geometryn(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometryn(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_geometryn_collection'; | |
ALTER FUNCTION public.st_geometryn(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 594 (class 1255 OID 18950) | |
-- Dependencies: 6 1102 | |
-- Name: st_geometrytype(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geometrytype(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geometry_geometrytype'; | |
ALTER FUNCTION public.st_geometrytype(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 595 (class 1255 OID 18951) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromewkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromewkb(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOMFromWKB'; | |
ALTER FUNCTION public.st_geomfromewkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 596 (class 1255 OID 18952) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromewkt(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromewkt(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'parse_WKT_lwgeom'; | |
ALTER FUNCTION public.st_geomfromewkt(text) OWNER TO postgres; | |
-- | |
-- TOC entry 597 (class 1255 OID 18953) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromgml(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromgml(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geom_from_gml'; | |
ALTER FUNCTION public.st_geomfromgml(text) OWNER TO postgres; | |
-- | |
-- TOC entry 598 (class 1255 OID 18954) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromkml(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromkml(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geom_from_kml'; | |
ALTER FUNCTION public.st_geomfromkml(text) OWNER TO postgres; | |
-- | |
-- TOC entry 599 (class 1255 OID 18955) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromtext(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.st_geomfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 600 (class 1255 OID 18956) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromtext(text, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.st_geomfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 601 (class 1255 OID 18957) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromwkb(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_WKB'; | |
ALTER FUNCTION public.st_geomfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 602 (class 1255 OID 18958) | |
-- Dependencies: 6 1102 | |
-- Name: st_geomfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_geomfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_SetSRID(ST_GeomFromWKB($1), $2)$_$; | |
ALTER FUNCTION public.st_geomfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 603 (class 1255 OID 18959) | |
-- Dependencies: 6 1102 | |
-- Name: st_gmltosql(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_gmltosql(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geom_from_gml'; | |
ALTER FUNCTION public.st_gmltosql(text) OWNER TO postgres; | |
-- | |
-- TOC entry 604 (class 1255 OID 18960) | |
-- Dependencies: 6 1102 | |
-- Name: st_hasarc(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_hasarc(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_has_arc'; | |
ALTER FUNCTION public.st_hasarc(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 605 (class 1255 OID 18961) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_hausdorffdistance(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_hausdorffdistance(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'hausdorffdistance'; | |
ALTER FUNCTION public.st_hausdorffdistance(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 606 (class 1255 OID 18962) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_hausdorffdistance(geometry, geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_hausdorffdistance(geometry, geometry, double precision) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'hausdorffdistancedensify'; | |
ALTER FUNCTION public.st_hausdorffdistance(geometry, geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 607 (class 1255 OID 18963) | |
-- Dependencies: 6 1096 | |
-- Name: st_height(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_height(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getHeight'; | |
ALTER FUNCTION public.st_height(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 608 (class 1255 OID 18964) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_interiorringn(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_interiorringn(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_interiorringn_polygon'; | |
ALTER FUNCTION public.st_interiorringn(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 609 (class 1255 OID 18965) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_intersection(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_intersection(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'intersection'; | |
ALTER FUNCTION public.st_intersection(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 610 (class 1255 OID 18966) | |
-- Dependencies: 6 1099 1099 1099 | |
-- Name: st_intersection(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_intersection(geography, geography) RETURNS geography | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT geography(ST_Transform(ST_Intersection(ST_Transform(geometry($1), _ST_BestSRID($1, $2)), ST_Transform(geometry($2), _ST_BestSRID($1, $2))), 4326))$_$; | |
ALTER FUNCTION public.st_intersection(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 611 (class 1255 OID 18967) | |
-- Dependencies: 6 1102 | |
-- Name: st_intersection(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_intersection(text, text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Intersection($1::geometry, $2::geometry); $_$; | |
ALTER FUNCTION public.st_intersection(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 612 (class 1255 OID 18968) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_intersects(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_intersects(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Intersects($1,$2)$_$; | |
ALTER FUNCTION public.st_intersects(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 613 (class 1255 OID 18969) | |
-- Dependencies: 6 1099 1099 | |
-- Name: st_intersects(geography, geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_intersects(geography, geography) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT $1 && $2 AND _ST_Distance($1, $2, 0.0, false) < 0.00001$_$; | |
ALTER FUNCTION public.st_intersects(geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 614 (class 1255 OID 18970) | |
-- Dependencies: 6 | |
-- Name: st_intersects(text, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_intersects(text, text) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Intersects($1::geometry, $2::geometry); $_$; | |
ALTER FUNCTION public.st_intersects(text, text) OWNER TO postgres; | |
-- | |
-- TOC entry 615 (class 1255 OID 18971) | |
-- Dependencies: 6 1102 | |
-- Name: st_isclosed(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_isclosed(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_isclosed_linestring'; | |
ALTER FUNCTION public.st_isclosed(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 616 (class 1255 OID 18972) | |
-- Dependencies: 6 1102 | |
-- Name: st_isempty(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_isempty(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_isempty'; | |
ALTER FUNCTION public.st_isempty(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 617 (class 1255 OID 18973) | |
-- Dependencies: 6 1102 | |
-- Name: st_isring(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_isring(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'isring'; | |
ALTER FUNCTION public.st_isring(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 618 (class 1255 OID 18974) | |
-- Dependencies: 6 1102 | |
-- Name: st_issimple(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_issimple(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'issimple'; | |
ALTER FUNCTION public.st_issimple(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 619 (class 1255 OID 18975) | |
-- Dependencies: 6 1102 | |
-- Name: st_isvalid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_isvalid(geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'isvalid'; | |
ALTER FUNCTION public.st_isvalid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 620 (class 1255 OID 18976) | |
-- Dependencies: 6 1102 | |
-- Name: st_isvalidreason(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_isvalidreason(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'isvalidreason'; | |
ALTER FUNCTION public.st_isvalidreason(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 621 (class 1255 OID 18977) | |
-- Dependencies: 6 1102 | |
-- Name: st_length(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length2d_linestring'; | |
ALTER FUNCTION public.st_length(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 623 (class 1255 OID 18979) | |
-- Dependencies: 6 1099 | |
-- Name: st_length(geography); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length(geography) RETURNS double precision | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT ST_Length($1, true)$_$; | |
ALTER FUNCTION public.st_length(geography) OWNER TO postgres; | |
-- | |
-- TOC entry 624 (class 1255 OID 18980) | |
-- Dependencies: 6 | |
-- Name: st_length(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length(text) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT ST_Length($1::geometry); $_$; | |
ALTER FUNCTION public.st_length(text) OWNER TO postgres; | |
-- | |
-- TOC entry 622 (class 1255 OID 18978) | |
-- Dependencies: 6 1099 | |
-- Name: st_length(geography, boolean); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length(geography, boolean) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'geography_length'; | |
ALTER FUNCTION public.st_length(geography, boolean) OWNER TO postgres; | |
-- | |
-- TOC entry 625 (class 1255 OID 18981) | |
-- Dependencies: 6 1102 | |
-- Name: st_length2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length2d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length2d_linestring'; | |
ALTER FUNCTION public.st_length2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 626 (class 1255 OID 18982) | |
-- Dependencies: 6 1102 1113 | |
-- Name: st_length2d_spheroid(geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length2d_spheroid(geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_length2d_ellipsoid'; | |
ALTER FUNCTION public.st_length2d_spheroid(geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 627 (class 1255 OID 18983) | |
-- Dependencies: 6 1102 | |
-- Name: st_length3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length3d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_linestring'; | |
ALTER FUNCTION public.st_length3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 628 (class 1255 OID 18984) | |
-- Dependencies: 6 1102 1113 | |
-- Name: st_length3d_spheroid(geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length3d_spheroid(geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_ellipsoid_linestring'; | |
ALTER FUNCTION public.st_length3d_spheroid(geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 629 (class 1255 OID 18985) | |
-- Dependencies: 6 1102 1113 | |
-- Name: st_length_spheroid(geometry, spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_length_spheroid(geometry, spheroid) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'LWGEOM_length_ellipsoid_linestring'; | |
ALTER FUNCTION public.st_length_spheroid(geometry, spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 630 (class 1255 OID 18986) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_line_interpolate_point(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_line_interpolate_point(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_interpolate_point'; | |
ALTER FUNCTION public.st_line_interpolate_point(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 631 (class 1255 OID 18987) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_line_locate_point(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_line_locate_point(geometry, geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_locate_point'; | |
ALTER FUNCTION public.st_line_locate_point(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 632 (class 1255 OID 18988) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_line_substring(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_line_substring(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_substring'; | |
ALTER FUNCTION public.st_line_substring(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 633 (class 1255 OID 18989) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_linecrossingdirection(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linecrossingdirection(geometry, geometry) RETURNS integer | |
LANGUAGE sql IMMUTABLE | |
AS $_$ SELECT CASE WHEN NOT $1 && $2 THEN 0 ELSE _ST_LineCrossingDirection($1,$2) END $_$; | |
ALTER FUNCTION public.st_linecrossingdirection(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 634 (class 1255 OID 18990) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_linefrommultipoint(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linefrommultipoint(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_from_mpoint'; | |
ALTER FUNCTION public.st_linefrommultipoint(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 635 (class 1255 OID 18991) | |
-- Dependencies: 6 1102 | |
-- Name: st_linefromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linefromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1)) = 'LINESTRING' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_linefromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 636 (class 1255 OID 18992) | |
-- Dependencies: 6 1102 | |
-- Name: st_linefromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linefromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1, $2)) = 'LINESTRING' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_linefromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 638 (class 1255 OID 18994) | |
-- Dependencies: 6 1102 | |
-- Name: st_linefromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linefromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'LINESTRING' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_linefromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 637 (class 1255 OID 18993) | |
-- Dependencies: 6 1102 | |
-- Name: st_linefromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linefromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'LINESTRING' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_linefromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 639 (class 1255 OID 18995) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_linemerge(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linemerge(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'linemerge'; | |
ALTER FUNCTION public.st_linemerge(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 641 (class 1255 OID 18997) | |
-- Dependencies: 6 1102 | |
-- Name: st_linestringfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linestringfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'LINESTRING' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_linestringfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 640 (class 1255 OID 18996) | |
-- Dependencies: 6 1102 | |
-- Name: st_linestringfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linestringfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'LINESTRING' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_linestringfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 642 (class 1255 OID 18998) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_linetocurve(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_linetocurve(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_line_desegmentize'; | |
ALTER FUNCTION public.st_linetocurve(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 643 (class 1255 OID 18999) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_locate_along_measure(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_locate_along_measure(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ SELECT locate_between_measures($1, $2, $2) $_$; | |
ALTER FUNCTION public.st_locate_along_measure(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 644 (class 1255 OID 19000) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_locate_between_measures(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_locate_between_measures(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_locate_between_m'; | |
ALTER FUNCTION public.st_locate_between_measures(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 645 (class 1255 OID 19001) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_locatebetweenelevations(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_locatebetweenelevations(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ST_LocateBetweenElevations'; | |
ALTER FUNCTION public.st_locatebetweenelevations(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 646 (class 1255 OID 19002) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_longestline(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_longestline(geometry, geometry) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_LongestLine(ST_ConvexHull($1), ST_ConvexHull($2))$_$; | |
ALTER FUNCTION public.st_longestline(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 647 (class 1255 OID 19003) | |
-- Dependencies: 6 1102 | |
-- Name: st_m(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_m(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_m_point'; | |
ALTER FUNCTION public.st_m(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 648 (class 1255 OID 19004) | |
-- Dependencies: 6 1087 1102 1102 | |
-- Name: st_makebox2d(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makebox2d(geometry, geometry) RETURNS box2d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX2DFLOAT4_construct'; | |
ALTER FUNCTION public.st_makebox2d(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 649 (class 1255 OID 19005) | |
-- Dependencies: 6 1090 1102 1102 | |
-- Name: st_makebox3d(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makebox3d(geometry, geometry) RETURNS box3d | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_construct'; | |
ALTER FUNCTION public.st_makebox3d(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 650 (class 1255 OID 19006) | |
-- Dependencies: 6 1102 | |
-- Name: st_makeenvelope(double precision, double precision, double precision, double precision, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makeenvelope(double precision, double precision, double precision, double precision, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ST_MakeEnvelope'; | |
ALTER FUNCTION public.st_makeenvelope(double precision, double precision, double precision, double precision, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 651 (class 1255 OID 19007) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_makeline(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makeline(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makeline_garray'; | |
ALTER FUNCTION public.st_makeline(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 652 (class 1255 OID 19008) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_makeline(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makeline(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makeline'; | |
ALTER FUNCTION public.st_makeline(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 653 (class 1255 OID 19009) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_makeline_garray(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makeline_garray(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makeline_garray'; | |
ALTER FUNCTION public.st_makeline_garray(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 654 (class 1255 OID 19010) | |
-- Dependencies: 6 1102 | |
-- Name: st_makepoint(double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makepoint(double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.st_makepoint(double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 655 (class 1255 OID 19011) | |
-- Dependencies: 6 1102 | |
-- Name: st_makepoint(double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makepoint(double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.st_makepoint(double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 656 (class 1255 OID 19012) | |
-- Dependencies: 6 1102 | |
-- Name: st_makepoint(double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makepoint(double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.st_makepoint(double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 657 (class 1255 OID 19013) | |
-- Dependencies: 6 1102 | |
-- Name: st_makepointm(double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makepointm(double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint3dm'; | |
ALTER FUNCTION public.st_makepointm(double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 659 (class 1255 OID 19015) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_makepolygon(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makepolygon(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoly'; | |
ALTER FUNCTION public.st_makepolygon(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 658 (class 1255 OID 19014) | |
-- Dependencies: 6 1102 1102 1104 | |
-- Name: st_makepolygon(geometry, geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_makepolygon(geometry, geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoly'; | |
ALTER FUNCTION public.st_makepolygon(geometry, geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 660 (class 1255 OID 19016) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_maxdistance(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_maxdistance(geometry, geometry) RETURNS double precision | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT _ST_MaxDistance(ST_ConvexHull($1), ST_ConvexHull($2))$_$; | |
ALTER FUNCTION public.st_maxdistance(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 661 (class 1255 OID 19017) | |
-- Dependencies: 6 1102 | |
-- Name: st_mem_size(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mem_size(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_mem_size'; | |
ALTER FUNCTION public.st_mem_size(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 663 (class 1255 OID 19020) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_minimumboundingcircle(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_minimumboundingcircle(geometry) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_MinimumBoundingCircle($1, 48)$_$; | |
ALTER FUNCTION public.st_minimumboundingcircle(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 662 (class 1255 OID 19018) | |
-- Dependencies: 6 1170 1102 1102 | |
-- Name: st_minimumboundingcircle(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_minimumboundingcircle(inputgeom geometry, segs_per_quarter integer) RETURNS geometry | |
LANGUAGE plpgsql IMMUTABLE STRICT | |
AS $$ | |
DECLARE | |
hull GEOMETRY; | |
ring GEOMETRY; | |
center GEOMETRY; | |
radius DOUBLE PRECISION; | |
dist DOUBLE PRECISION; | |
d DOUBLE PRECISION; | |
idx1 integer; | |
idx2 integer; | |
l1 GEOMETRY; | |
l2 GEOMETRY; | |
p1 GEOMETRY; | |
p2 GEOMETRY; | |
a1 DOUBLE PRECISION; | |
a2 DOUBLE PRECISION; | |
BEGIN | |
-- First compute the ConvexHull of the geometry | |
hull = ST_ConvexHull(inputgeom); | |
--A point really has no MBC | |
IF ST_GeometryType(hull) = 'ST_Point' THEN | |
RETURN hull; | |
END IF; | |
-- convert the hull perimeter to a linestring so we can manipulate individual points | |
--If its already a linestring force it to a closed linestring | |
ring = CASE WHEN ST_GeometryType(hull) = 'ST_LineString' THEN ST_AddPoint(hull, ST_StartPoint(hull)) ELSE ST_ExteriorRing(hull) END; | |
dist = 0; | |
-- Brute Force - check every pair | |
FOR i in 1 .. (ST_NumPoints(ring)-2) | |
LOOP | |
FOR j in i .. (ST_NumPoints(ring)-1) | |
LOOP | |
d = ST_Distance(ST_PointN(ring,i),ST_PointN(ring,j)); | |
-- Check the distance and update if larger | |
IF (d > dist) THEN | |
dist = d; | |
idx1 = i; | |
idx2 = j; | |
END IF; | |
END LOOP; | |
END LOOP; | |
-- We now have the diameter of the convex hull. The following line returns it if desired. | |
-- RETURN MakeLine(PointN(ring,idx1),PointN(ring,idx2)); | |
-- Now for the Minimum Bounding Circle. Since we know the two points furthest from each | |
-- other, the MBC must go through those two points. Start with those points as a diameter of a circle. | |
-- The radius is half the distance between them and the center is midway between them | |
radius = ST_Distance(ST_PointN(ring,idx1),ST_PointN(ring,idx2)) / 2.0; | |
center = ST_Line_interpolate_point(ST_MakeLine(ST_PointN(ring,idx1),ST_PointN(ring,idx2)),0.5); | |
-- Loop through each vertex and check if the distance from the center to the point | |
-- is greater than the current radius. | |
FOR k in 1 .. (ST_NumPoints(ring)-1) | |
LOOP | |
IF(k <> idx1 and k <> idx2) THEN | |
dist = ST_Distance(center,ST_PointN(ring,k)); | |
IF (dist > radius) THEN | |
-- We have to expand the circle. The new circle must pass trhough | |
-- three points - the two original diameters and this point. | |
-- Draw a line from the first diameter to this point | |
l1 = ST_Makeline(ST_PointN(ring,idx1),ST_PointN(ring,k)); | |
-- Compute the midpoint | |
p1 = ST_line_interpolate_point(l1,0.5); | |
-- Rotate the line 90 degrees around the midpoint (perpendicular bisector) | |
l1 = ST_Translate(ST_Rotate(ST_Translate(l1,-X(p1),-Y(p1)),pi()/2),X(p1),Y(p1)); | |
-- Compute the azimuth of the bisector | |
a1 = ST_Azimuth(ST_PointN(l1,1),ST_PointN(l1,2)); | |
-- Extend the line in each direction the new computed distance to insure they will intersect | |
l1 = ST_AddPoint(l1,ST_Makepoint(X(ST_PointN(l1,2))+sin(a1)*dist,Y(ST_PointN(l1,2))+cos(a1)*dist),-1); | |
l1 = ST_AddPoint(l1,ST_Makepoint(X(ST_PointN(l1,1))-sin(a1)*dist,Y(ST_PointN(l1,1))-cos(a1)*dist),0); | |
-- Repeat for the line from the point to the other diameter point | |
l2 = ST_Makeline(ST_PointN(ring,idx2),ST_PointN(ring,k)); | |
p2 = ST_Line_interpolate_point(l2,0.5); | |
l2 = ST_Translate(ST_Rotate(ST_Translate(l2,-X(p2),-Y(p2)),pi()/2),X(p2),Y(p2)); | |
a2 = ST_Azimuth(ST_PointN(l2,1),ST_PointN(l2,2)); | |
l2 = ST_AddPoint(l2,ST_Makepoint(X(ST_PointN(l2,2))+sin(a2)*dist,Y(ST_PointN(l2,2))+cos(a2)*dist),-1); | |
l2 = ST_AddPoint(l2,ST_Makepoint(X(ST_PointN(l2,1))-sin(a2)*dist,Y(ST_PointN(l2,1))-cos(a2)*dist),0); | |
-- The new center is the intersection of the two bisectors | |
center = ST_Intersection(l1,l2); | |
-- The new radius is the distance to any of the three points | |
radius = ST_Distance(center,ST_PointN(ring,idx1)); | |
END IF; | |
END IF; | |
END LOOP; | |
--DONE!! Return the MBC via the buffer command | |
RETURN ST_Buffer(center,radius,segs_per_quarter); | |
END; | |
$$; | |
ALTER FUNCTION public.st_minimumboundingcircle(inputgeom geometry, segs_per_quarter integer) OWNER TO postgres; | |
-- | |
-- TOC entry 665 (class 1255 OID 19022) | |
-- Dependencies: 6 1102 | |
-- Name: st_mlinefromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mlinefromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1)) = 'MULTILINESTRING' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mlinefromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 664 (class 1255 OID 19021) | |
-- Dependencies: 6 1102 | |
-- Name: st_mlinefromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mlinefromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE | |
WHEN geometrytype(GeomFromText($1, $2)) = 'MULTILINESTRING' | |
THEN GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mlinefromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 667 (class 1255 OID 19024) | |
-- Dependencies: 6 1102 | |
-- Name: st_mlinefromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mlinefromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'MULTILINESTRING' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mlinefromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 666 (class 1255 OID 19023) | |
-- Dependencies: 6 1102 | |
-- Name: st_mlinefromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mlinefromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'MULTILINESTRING' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mlinefromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 669 (class 1255 OID 19026) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpointfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpointfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1)) = 'MULTIPOINT' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpointfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 668 (class 1255 OID 19025) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpointfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpointfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromText($1, $2)) = 'MULTIPOINT' | |
THEN GeomFromText($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpointfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 672 (class 1255 OID 19028) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpointfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpointfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'MULTIPOINT' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpointfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 671 (class 1255 OID 19027) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpointfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpointfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1, $2)) = 'MULTIPOINT' | |
THEN GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpointfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 674 (class 1255 OID 19030) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpolyfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpolyfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1)) = 'MULTIPOLYGON' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpolyfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 673 (class 1255 OID 19029) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpolyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpolyfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1, $2)) = 'MULTIPOLYGON' | |
THEN ST_GeomFromText($1,$2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpolyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 676 (class 1255 OID 19032) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpolyfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpolyfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'MULTIPOLYGON' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpolyfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 675 (class 1255 OID 19031) | |
-- Dependencies: 6 1102 | |
-- Name: st_mpolyfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_mpolyfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'MULTIPOLYGON' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_mpolyfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 677 (class 1255 OID 19033) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_multi(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multi(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_force_multi'; | |
ALTER FUNCTION public.st_multi(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 678 (class 1255 OID 19034) | |
-- Dependencies: 6 1102 | |
-- Name: st_multilinefromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multilinefromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'MULTILINESTRING' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_multilinefromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 679 (class 1255 OID 19035) | |
-- Dependencies: 6 1102 | |
-- Name: st_multilinestringfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multilinestringfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_MLineFromText($1)$_$; | |
ALTER FUNCTION public.st_multilinestringfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 680 (class 1255 OID 19036) | |
-- Dependencies: 6 1102 | |
-- Name: st_multilinestringfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multilinestringfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MLineFromText($1, $2)$_$; | |
ALTER FUNCTION public.st_multilinestringfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 681 (class 1255 OID 19037) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipointfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipointfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPointFromText($1)$_$; | |
ALTER FUNCTION public.st_multipointfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 683 (class 1255 OID 19039) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipointfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipointfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'MULTIPOINT' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_multipointfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 682 (class 1255 OID 19038) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipointfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipointfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1,$2)) = 'MULTIPOINT' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_multipointfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 685 (class 1255 OID 19041) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipolyfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipolyfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'MULTIPOLYGON' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_multipolyfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 684 (class 1255 OID 19040) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipolyfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipolyfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'MULTIPOLYGON' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_multipolyfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 687 (class 1255 OID 19043) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipolygonfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipolygonfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPolyFromText($1)$_$; | |
ALTER FUNCTION public.st_multipolygonfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 686 (class 1255 OID 19042) | |
-- Dependencies: 6 1102 | |
-- Name: st_multipolygonfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_multipolygonfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT MPolyFromText($1, $2)$_$; | |
ALTER FUNCTION public.st_multipolygonfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 688 (class 1255 OID 19044) | |
-- Dependencies: 6 1102 | |
-- Name: st_ndims(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_ndims(geometry) RETURNS smallint | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_ndims'; | |
ALTER FUNCTION public.st_ndims(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 689 (class 1255 OID 19045) | |
-- Dependencies: 6 1102 | |
-- Name: st_npoints(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_npoints(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_npoints'; | |
ALTER FUNCTION public.st_npoints(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 690 (class 1255 OID 19046) | |
-- Dependencies: 6 1102 | |
-- Name: st_nrings(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_nrings(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_nrings'; | |
ALTER FUNCTION public.st_nrings(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 691 (class 1255 OID 19047) | |
-- Dependencies: 6 1102 | |
-- Name: st_numgeometries(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_numgeometries(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numgeometries_collection'; | |
ALTER FUNCTION public.st_numgeometries(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 692 (class 1255 OID 19048) | |
-- Dependencies: 6 1102 | |
-- Name: st_numinteriorring(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_numinteriorring(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numinteriorrings_polygon'; | |
ALTER FUNCTION public.st_numinteriorring(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 693 (class 1255 OID 19049) | |
-- Dependencies: 6 1102 | |
-- Name: st_numinteriorrings(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_numinteriorrings(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numinteriorrings_polygon'; | |
ALTER FUNCTION public.st_numinteriorrings(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 694 (class 1255 OID 19050) | |
-- Dependencies: 6 1102 | |
-- Name: st_numpoints(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_numpoints(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_numpoints_linestring'; | |
ALTER FUNCTION public.st_numpoints(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 695 (class 1255 OID 19051) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_orderingequals(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_orderingequals(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT $1 ~= $2 AND _ST_OrderingEquals($1, $2) | |
$_$; | |
ALTER FUNCTION public.st_orderingequals(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 696 (class 1255 OID 19052) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_overlaps(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_overlaps(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Overlaps($1,$2)$_$; | |
ALTER FUNCTION public.st_overlaps(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 697 (class 1255 OID 19053) | |
-- Dependencies: 6 1102 | |
-- Name: st_perimeter(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_perimeter(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_perimeter2d_poly'; | |
ALTER FUNCTION public.st_perimeter(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 698 (class 1255 OID 19054) | |
-- Dependencies: 6 1102 | |
-- Name: st_perimeter2d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_perimeter2d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_perimeter2d_poly'; | |
ALTER FUNCTION public.st_perimeter2d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 699 (class 1255 OID 19055) | |
-- Dependencies: 6 1102 | |
-- Name: st_perimeter3d(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_perimeter3d(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_perimeter_poly'; | |
ALTER FUNCTION public.st_perimeter3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 700 (class 1255 OID 19056) | |
-- Dependencies: 6 1102 | |
-- Name: st_point(double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_point(double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_makepoint'; | |
ALTER FUNCTION public.st_point(double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 701 (class 1255 OID 19057) | |
-- Dependencies: 6 1102 | |
-- Name: st_point_inside_circle(geometry, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_point_inside_circle(geometry, double precision, double precision, double precision) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_inside_circle_point'; | |
ALTER FUNCTION public.st_point_inside_circle(geometry, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 702 (class 1255 OID 19058) | |
-- Dependencies: 6 1102 | |
-- Name: st_pointfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_pointfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1)) = 'POINT' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_pointfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 703 (class 1255 OID 19059) | |
-- Dependencies: 6 1102 | |
-- Name: st_pointfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_pointfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1, $2)) = 'POINT' | |
THEN ST_GeomFromText($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_pointfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 706 (class 1255 OID 19061) | |
-- Dependencies: 6 1102 | |
-- Name: st_pointfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_pointfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'POINT' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_pointfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 705 (class 1255 OID 19060) | |
-- Dependencies: 6 1102 | |
-- Name: st_pointfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_pointfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'POINT' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_pointfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 707 (class 1255 OID 19062) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_pointn(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_pointn(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_pointn_linestring'; | |
ALTER FUNCTION public.st_pointn(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 708 (class 1255 OID 19063) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_pointonsurface(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_pointonsurface(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'pointonsurface'; | |
ALTER FUNCTION public.st_pointonsurface(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 709 (class 1255 OID 19064) | |
-- Dependencies: 6 1102 | |
-- Name: st_polyfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polyfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1)) = 'POLYGON' | |
THEN ST_GeomFromText($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_polyfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 710 (class 1255 OID 19065) | |
-- Dependencies: 6 1102 | |
-- Name: st_polyfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polyfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromText($1, $2)) = 'POLYGON' | |
THEN ST_GeomFromText($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_polyfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 712 (class 1255 OID 19067) | |
-- Dependencies: 6 1102 | |
-- Name: st_polyfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polyfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1)) = 'POLYGON' | |
THEN ST_GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_polyfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 711 (class 1255 OID 19066) | |
-- Dependencies: 6 1102 | |
-- Name: st_polyfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polyfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1, $2)) = 'POLYGON' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_polyfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 713 (class 1255 OID 19068) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_polygon(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygon(geometry, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT setSRID(makepolygon($1), $2) | |
$_$; | |
ALTER FUNCTION public.st_polygon(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 715 (class 1255 OID 19070) | |
-- Dependencies: 6 1102 | |
-- Name: st_polygonfromtext(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygonfromtext(text) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_PolyFromText($1)$_$; | |
ALTER FUNCTION public.st_polygonfromtext(text) OWNER TO postgres; | |
-- | |
-- TOC entry 714 (class 1255 OID 19069) | |
-- Dependencies: 6 1102 | |
-- Name: st_polygonfromtext(text, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygonfromtext(text, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT PolyFromText($1, $2)$_$; | |
ALTER FUNCTION public.st_polygonfromtext(text, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 717 (class 1255 OID 19072) | |
-- Dependencies: 6 1102 | |
-- Name: st_polygonfromwkb(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygonfromwkb(bytea) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(GeomFromWKB($1)) = 'POLYGON' | |
THEN GeomFromWKB($1) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_polygonfromwkb(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 716 (class 1255 OID 19071) | |
-- Dependencies: 6 1102 | |
-- Name: st_polygonfromwkb(bytea, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygonfromwkb(bytea, integer) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$ | |
SELECT CASE WHEN geometrytype(ST_GeomFromWKB($1,$2)) = 'POLYGON' | |
THEN ST_GeomFromWKB($1, $2) | |
ELSE NULL END | |
$_$; | |
ALTER FUNCTION public.st_polygonfromwkb(bytea, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 718 (class 1255 OID 19073) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_polygonize(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygonize(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'polygonize_garray'; | |
ALTER FUNCTION public.st_polygonize(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 719 (class 1255 OID 19074) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_polygonize_garray(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_polygonize_garray(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'polygonize_garray'; | |
ALTER FUNCTION public.st_polygonize_garray(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 720 (class 1255 OID 19075) | |
-- Dependencies: 6 | |
-- Name: st_postgis_gist_joinsel(internal, oid, internal, smallint); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_postgis_gist_joinsel(internal, oid, internal, smallint) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_joinsel'; | |
ALTER FUNCTION public.st_postgis_gist_joinsel(internal, oid, internal, smallint) OWNER TO postgres; | |
-- | |
-- TOC entry 721 (class 1255 OID 19076) | |
-- Dependencies: 6 | |
-- Name: st_postgis_gist_sel(internal, oid, internal, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_postgis_gist_sel(internal, oid, internal, integer) RETURNS double precision | |
LANGUAGE c | |
AS '$libdir/postgis-1.5', 'LWGEOM_gist_sel'; | |
ALTER FUNCTION public.st_postgis_gist_sel(internal, oid, internal, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 722 (class 1255 OID 19077) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_relate(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_relate(geometry, geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'relate_full'; | |
ALTER FUNCTION public.st_relate(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 723 (class 1255 OID 19078) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_relate(geometry, geometry, text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_relate(geometry, geometry, text) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'relate_pattern'; | |
ALTER FUNCTION public.st_relate(geometry, geometry, text) OWNER TO postgres; | |
-- | |
-- TOC entry 724 (class 1255 OID 19079) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_removepoint(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_removepoint(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_removepoint'; | |
ALTER FUNCTION public.st_removepoint(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 725 (class 1255 OID 19080) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_reverse(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_reverse(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_reverse'; | |
ALTER FUNCTION public.st_reverse(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 726 (class 1255 OID 19081) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_rotate(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_rotate(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT rotateZ($1, $2)$_$; | |
ALTER FUNCTION public.st_rotate(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 727 (class 1255 OID 19082) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_rotatex(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_rotatex(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, 1, 0, 0, 0, cos($2), -sin($2), 0, sin($2), cos($2), 0, 0, 0)$_$; | |
ALTER FUNCTION public.st_rotatex(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 728 (class 1255 OID 19083) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_rotatey(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_rotatey(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, cos($2), 0, sin($2), 0, 1, 0, -sin($2), 0, cos($2), 0, 0, 0)$_$; | |
ALTER FUNCTION public.st_rotatey(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 729 (class 1255 OID 19084) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_rotatez(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_rotatez(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, cos($2), -sin($2), 0, sin($2), cos($2), 0, 0, 0, 1, 0, 0, 0)$_$; | |
ALTER FUNCTION public.st_rotatez(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 731 (class 1255 OID 19086) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_scale(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_scale(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT scale($1, $2, $3, 1)$_$; | |
ALTER FUNCTION public.st_scale(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 730 (class 1255 OID 19085) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_scale(geometry, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_scale(geometry, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, $2, 0, 0, 0, $3, 0, 0, 0, $4, 0, 0, 0)$_$; | |
ALTER FUNCTION public.st_scale(geometry, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 732 (class 1255 OID 19087) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_segmentize(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_segmentize(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_segmentize2d'; | |
ALTER FUNCTION public.st_segmentize(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 733 (class 1255 OID 19088) | |
-- Dependencies: 6 1096 1096 | |
-- Name: st_setfactor(chip, real); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_setfactor(chip, real) RETURNS chip | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_setFactor'; | |
ALTER FUNCTION public.st_setfactor(chip, real) OWNER TO postgres; | |
-- | |
-- TOC entry 734 (class 1255 OID 19089) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_setpoint(geometry, integer, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_setpoint(geometry, integer, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_setpoint_linestring'; | |
ALTER FUNCTION public.st_setpoint(geometry, integer, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 735 (class 1255 OID 19090) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_setsrid(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_setsrid(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_setSRID'; | |
ALTER FUNCTION public.st_setsrid(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 736 (class 1255 OID 19091) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_shift_longitude(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_shift_longitude(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_longitude_shift'; | |
ALTER FUNCTION public.st_shift_longitude(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 737 (class 1255 OID 19092) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_shortestline(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_shortestline(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_shortestline2d'; | |
ALTER FUNCTION public.st_shortestline(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 738 (class 1255 OID 19093) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_simplify(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_simplify(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_simplify2d'; | |
ALTER FUNCTION public.st_simplify(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 739 (class 1255 OID 19094) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_simplifypreservetopology(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_simplifypreservetopology(geometry, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT COST 100 | |
AS '$libdir/postgis-1.5', 'topologypreservesimplify'; | |
ALTER FUNCTION public.st_simplifypreservetopology(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 740 (class 1255 OID 19097) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_snaptogrid(geometry, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_snaptogrid(geometry, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_SnapToGrid($1, 0, 0, $2, $2)$_$; | |
ALTER FUNCTION public.st_snaptogrid(geometry, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 704 (class 1255 OID 19096) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_snaptogrid(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_snaptogrid(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT ST_SnapToGrid($1, 0, 0, $2, $3)$_$; | |
ALTER FUNCTION public.st_snaptogrid(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 670 (class 1255 OID 19095) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_snaptogrid(geometry, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_snaptogrid(geometry, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_snaptogrid'; | |
ALTER FUNCTION public.st_snaptogrid(geometry, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 741 (class 1255 OID 19098) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_snaptogrid(geometry, geometry, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_snaptogrid(geometry, geometry, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_snaptogrid_pointoff'; | |
ALTER FUNCTION public.st_snaptogrid(geometry, geometry, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 742 (class 1255 OID 19099) | |
-- Dependencies: 6 1113 | |
-- Name: st_spheroid_in(cstring); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_spheroid_in(cstring) RETURNS spheroid | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ellipsoid_in'; | |
ALTER FUNCTION public.st_spheroid_in(cstring) OWNER TO postgres; | |
-- | |
-- TOC entry 743 (class 1255 OID 19100) | |
-- Dependencies: 6 1113 | |
-- Name: st_spheroid_out(spheroid); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_spheroid_out(spheroid) RETURNS cstring | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'ellipsoid_out'; | |
ALTER FUNCTION public.st_spheroid_out(spheroid) OWNER TO postgres; | |
-- | |
-- TOC entry 744 (class 1255 OID 19101) | |
-- Dependencies: 6 1096 | |
-- Name: st_srid(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_srid(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getSRID'; | |
ALTER FUNCTION public.st_srid(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 745 (class 1255 OID 19102) | |
-- Dependencies: 6 1102 | |
-- Name: st_srid(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_srid(geometry) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_getSRID'; | |
ALTER FUNCTION public.st_srid(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 746 (class 1255 OID 19103) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_startpoint(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_startpoint(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_startpoint_linestring'; | |
ALTER FUNCTION public.st_startpoint(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 747 (class 1255 OID 19104) | |
-- Dependencies: 6 1102 | |
-- Name: st_summary(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_summary(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_summary'; | |
ALTER FUNCTION public.st_summary(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 748 (class 1255 OID 19105) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_symdifference(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_symdifference(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'symdifference'; | |
ALTER FUNCTION public.st_symdifference(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 749 (class 1255 OID 19106) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_symmetricdifference(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_symmetricdifference(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'symdifference'; | |
ALTER FUNCTION public.st_symmetricdifference(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 750 (class 1255 OID 19107) | |
-- Dependencies: 6 1102 | |
-- Name: st_text(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_text(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_text'; | |
ALTER FUNCTION public.st_text(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 751 (class 1255 OID 19108) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_touches(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_touches(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Touches($1,$2)$_$; | |
ALTER FUNCTION public.st_touches(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 752 (class 1255 OID 19109) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_transform(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_transform(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'transform'; | |
ALTER FUNCTION public.st_transform(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 754 (class 1255 OID 19111) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_translate(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_translate(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT translate($1, $2, $3, 0)$_$; | |
ALTER FUNCTION public.st_translate(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 753 (class 1255 OID 19110) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_translate(geometry, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_translate(geometry, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, 1, 0, 0, 0, 1, 0, 0, 0, 1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.st_translate(geometry, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 755 (class 1255 OID 19112) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_transscale(geometry, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_transscale(geometry, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, $4, 0, 0, 0, $5, 0, | |
0, 0, 1, $2 * $4, $3 * $5, 0)$_$; | |
ALTER FUNCTION public.st_transscale(geometry, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 757 (class 1255 OID 19114) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_union(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_union(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'pgis_union_geometry_array'; | |
ALTER FUNCTION public.st_union(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 756 (class 1255 OID 19113) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: st_union(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_union(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'geomunion'; | |
ALTER FUNCTION public.st_union(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 758 (class 1255 OID 19115) | |
-- Dependencies: 6 1102 1104 | |
-- Name: st_unite_garray(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_unite_garray(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'pgis_union_geometry_array'; | |
ALTER FUNCTION public.st_unite_garray(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 759 (class 1255 OID 19116) | |
-- Dependencies: 6 1096 | |
-- Name: st_width(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_width(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getWidth'; | |
ALTER FUNCTION public.st_width(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 760 (class 1255 OID 19117) | |
-- Dependencies: 6 1102 1102 | |
-- Name: st_within(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_within(geometry, geometry) RETURNS boolean | |
LANGUAGE sql IMMUTABLE | |
AS $_$SELECT $1 && $2 AND _ST_Within($1,$2)$_$; | |
ALTER FUNCTION public.st_within(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 761 (class 1255 OID 19118) | |
-- Dependencies: 6 1102 | |
-- Name: st_wkbtosql(bytea); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_wkbtosql(bytea) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_WKB'; | |
ALTER FUNCTION public.st_wkbtosql(bytea) OWNER TO postgres; | |
-- | |
-- TOC entry 762 (class 1255 OID 19119) | |
-- Dependencies: 6 1102 | |
-- Name: st_wkttosql(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_wkttosql(text) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_from_text'; | |
ALTER FUNCTION public.st_wkttosql(text) OWNER TO postgres; | |
-- | |
-- TOC entry 763 (class 1255 OID 19120) | |
-- Dependencies: 6 1102 | |
-- Name: st_x(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_x(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_x_point'; | |
ALTER FUNCTION public.st_x(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 764 (class 1255 OID 19121) | |
-- Dependencies: 6 1090 | |
-- Name: st_xmax(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_xmax(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_xmax'; | |
ALTER FUNCTION public.st_xmax(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 765 (class 1255 OID 19122) | |
-- Dependencies: 6 1090 | |
-- Name: st_xmin(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_xmin(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_xmin'; | |
ALTER FUNCTION public.st_xmin(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 766 (class 1255 OID 19123) | |
-- Dependencies: 6 1102 | |
-- Name: st_y(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_y(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_y_point'; | |
ALTER FUNCTION public.st_y(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 767 (class 1255 OID 19124) | |
-- Dependencies: 6 1090 | |
-- Name: st_ymax(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_ymax(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_ymax'; | |
ALTER FUNCTION public.st_ymax(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 768 (class 1255 OID 19125) | |
-- Dependencies: 6 1090 | |
-- Name: st_ymin(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_ymin(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_ymin'; | |
ALTER FUNCTION public.st_ymin(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 769 (class 1255 OID 19126) | |
-- Dependencies: 6 1102 | |
-- Name: st_z(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_z(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_z_point'; | |
ALTER FUNCTION public.st_z(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 770 (class 1255 OID 19127) | |
-- Dependencies: 6 1090 | |
-- Name: st_zmax(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_zmax(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_zmax'; | |
ALTER FUNCTION public.st_zmax(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 771 (class 1255 OID 19128) | |
-- Dependencies: 6 1102 | |
-- Name: st_zmflag(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_zmflag(geometry) RETURNS smallint | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_zmflag'; | |
ALTER FUNCTION public.st_zmflag(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 772 (class 1255 OID 19129) | |
-- Dependencies: 6 1090 | |
-- Name: st_zmin(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION st_zmin(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_zmin'; | |
ALTER FUNCTION public.st_zmin(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 773 (class 1255 OID 19130) | |
-- Dependencies: 6 1102 1102 | |
-- Name: startpoint(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION startpoint(geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_startpoint_linestring'; | |
ALTER FUNCTION public.startpoint(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 774 (class 1255 OID 19131) | |
-- Dependencies: 6 1102 | |
-- Name: summary(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION summary(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_summary'; | |
ALTER FUNCTION public.summary(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 775 (class 1255 OID 19132) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: symdifference(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION symdifference(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'symdifference'; | |
ALTER FUNCTION public.symdifference(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 776 (class 1255 OID 19133) | |
-- Dependencies: 6 1102 1102 1102 | |
-- Name: symmetricdifference(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION symmetricdifference(geometry, geometry) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'symdifference'; | |
ALTER FUNCTION public.symmetricdifference(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 777 (class 1255 OID 19134) | |
-- Dependencies: 6 1102 | |
-- Name: text(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION text(geometry) RETURNS text | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_to_text'; | |
ALTER FUNCTION public.text(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 778 (class 1255 OID 19135) | |
-- Dependencies: 6 1102 1102 | |
-- Name: touches(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION touches(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'touches'; | |
ALTER FUNCTION public.touches(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 779 (class 1255 OID 19136) | |
-- Dependencies: 6 1102 1102 | |
-- Name: transform(geometry, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION transform(geometry, integer) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'transform'; | |
ALTER FUNCTION public.transform(geometry, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 781 (class 1255 OID 19138) | |
-- Dependencies: 6 1102 1102 | |
-- Name: translate(geometry, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION translate(geometry, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT translate($1, $2, $3, 0)$_$; | |
ALTER FUNCTION public.translate(geometry, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 780 (class 1255 OID 19137) | |
-- Dependencies: 6 1102 1102 | |
-- Name: translate(geometry, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION translate(geometry, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, 1, 0, 0, 0, 1, 0, 0, 0, 1, $2, $3, $4)$_$; | |
ALTER FUNCTION public.translate(geometry, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 782 (class 1255 OID 19139) | |
-- Dependencies: 6 1102 1102 | |
-- Name: transscale(geometry, double precision, double precision, double precision, double precision); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION transscale(geometry, double precision, double precision, double precision, double precision) RETURNS geometry | |
LANGUAGE sql IMMUTABLE STRICT | |
AS $_$SELECT affine($1, $4, 0, 0, 0, $5, 0, | |
0, 0, 1, $2 * $4, $3 * $5, 0)$_$; | |
ALTER FUNCTION public.transscale(geometry, double precision, double precision, double precision, double precision) OWNER TO postgres; | |
-- | |
-- TOC entry 783 (class 1255 OID 19140) | |
-- Dependencies: 6 1102 1104 | |
-- Name: unite_garray(geometry[]); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION unite_garray(geometry[]) RETURNS geometry | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'pgis_union_geometry_array'; | |
ALTER FUNCTION public.unite_garray(geometry[]) OWNER TO postgres; | |
-- | |
-- TOC entry 784 (class 1255 OID 19141) | |
-- Dependencies: 6 1170 | |
-- Name: unlockrows(text); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION unlockrows(text) RETURNS integer | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
ret int; | |
BEGIN | |
IF NOT LongTransactionsEnabled() THEN | |
RAISE EXCEPTION 'Long transaction support disabled, use EnableLongTransaction() to enable.'; | |
END IF; | |
EXECUTE 'DELETE FROM authorization_table where authid = ' || | |
quote_literal($1); | |
GET DIAGNOSTICS ret = ROW_COUNT; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.unlockrows(text) OWNER TO postgres; | |
-- | |
-- TOC entry 787 (class 1255 OID 19144) | |
-- Dependencies: 6 1170 | |
-- Name: updategeometrysrid(character varying, character varying, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION updategeometrysrid(character varying, character varying, integer) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
ret text; | |
BEGIN | |
SELECT UpdateGeometrySRID('','',$1,$2,$3) into ret; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.updategeometrysrid(character varying, character varying, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 786 (class 1255 OID 19143) | |
-- Dependencies: 6 1170 | |
-- Name: updategeometrysrid(character varying, character varying, character varying, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION updategeometrysrid(character varying, character varying, character varying, integer) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
ret text; | |
BEGIN | |
SELECT UpdateGeometrySRID('',$1,$2,$3,$4) into ret; | |
RETURN ret; | |
END; | |
$_$; | |
ALTER FUNCTION public.updategeometrysrid(character varying, character varying, character varying, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 785 (class 1255 OID 19142) | |
-- Dependencies: 6 1170 | |
-- Name: updategeometrysrid(character varying, character varying, character varying, character varying, integer); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION updategeometrysrid(character varying, character varying, character varying, character varying, integer) RETURNS text | |
LANGUAGE plpgsql STRICT | |
AS $_$ | |
DECLARE | |
catalog_name alias for $1; | |
schema_name alias for $2; | |
table_name alias for $3; | |
column_name alias for $4; | |
new_srid alias for $5; | |
myrec RECORD; | |
okay boolean; | |
cname varchar; | |
real_schema name; | |
BEGIN | |
-- Find, check or fix schema_name | |
IF ( schema_name != '' ) THEN | |
okay = 'f'; | |
FOR myrec IN SELECT nspname FROM pg_namespace WHERE text(nspname) = schema_name LOOP | |
okay := 't'; | |
END LOOP; | |
IF ( okay <> 't' ) THEN | |
RAISE EXCEPTION 'Invalid schema name'; | |
ELSE | |
real_schema = schema_name; | |
END IF; | |
ELSE | |
SELECT INTO real_schema current_schema()::text; | |
END IF; | |
-- Find out if the column is in the geometry_columns table | |
okay = 'f'; | |
FOR myrec IN SELECT * from geometry_columns where f_table_schema = text(real_schema) and f_table_name = table_name and f_geometry_column = column_name LOOP | |
okay := 't'; | |
END LOOP; | |
IF (okay <> 't') THEN | |
RAISE EXCEPTION 'column not found in geometry_columns table'; | |
RETURN 'f'; | |
END IF; | |
-- Update ref from geometry_columns table | |
EXECUTE 'UPDATE geometry_columns SET SRID = ' || new_srid::text || | |
' where f_table_schema = ' || | |
quote_literal(real_schema) || ' and f_table_name = ' || | |
quote_literal(table_name) || ' and f_geometry_column = ' || | |
quote_literal(column_name); | |
-- Make up constraint name | |
cname = 'enforce_srid_' || column_name; | |
-- Drop enforce_srid constraint | |
EXECUTE 'ALTER TABLE ' || quote_ident(real_schema) || | |
'.' || quote_ident(table_name) || | |
' DROP constraint ' || quote_ident(cname); | |
-- Update geometries SRID | |
EXECUTE 'UPDATE ' || quote_ident(real_schema) || | |
'.' || quote_ident(table_name) || | |
' SET ' || quote_ident(column_name) || | |
' = setSRID(' || quote_ident(column_name) || | |
', ' || new_srid::text || ')'; | |
-- Reset enforce_srid constraint | |
EXECUTE 'ALTER TABLE ' || quote_ident(real_schema) || | |
'.' || quote_ident(table_name) || | |
' ADD constraint ' || quote_ident(cname) || | |
' CHECK (srid(' || quote_ident(column_name) || | |
') = ' || new_srid::text || ')'; | |
RETURN real_schema || '.' || table_name || '.' || column_name ||' SRID changed to ' || new_srid::text; | |
END; | |
$_$; | |
ALTER FUNCTION public.updategeometrysrid(character varying, character varying, character varying, character varying, integer) OWNER TO postgres; | |
-- | |
-- TOC entry 788 (class 1255 OID 19145) | |
-- Dependencies: 6 1096 | |
-- Name: width(chip); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION width(chip) RETURNS integer | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'CHIP_getWidth'; | |
ALTER FUNCTION public.width(chip) OWNER TO postgres; | |
-- | |
-- TOC entry 789 (class 1255 OID 19146) | |
-- Dependencies: 6 1102 1102 | |
-- Name: within(geometry, geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION within(geometry, geometry) RETURNS boolean | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'within'; | |
ALTER FUNCTION public.within(geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 790 (class 1255 OID 19147) | |
-- Dependencies: 6 1102 | |
-- Name: x(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION x(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_x_point'; | |
ALTER FUNCTION public.x(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 791 (class 1255 OID 19148) | |
-- Dependencies: 6 1090 | |
-- Name: xmax(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION xmax(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_xmax'; | |
ALTER FUNCTION public.xmax(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 792 (class 1255 OID 19149) | |
-- Dependencies: 6 1090 | |
-- Name: xmin(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION xmin(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_xmin'; | |
ALTER FUNCTION public.xmin(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 793 (class 1255 OID 19150) | |
-- Dependencies: 6 1102 | |
-- Name: y(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION y(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_y_point'; | |
ALTER FUNCTION public.y(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 794 (class 1255 OID 19151) | |
-- Dependencies: 6 1090 | |
-- Name: ymax(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION ymax(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_ymax'; | |
ALTER FUNCTION public.ymax(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 795 (class 1255 OID 19152) | |
-- Dependencies: 6 1090 | |
-- Name: ymin(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION ymin(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_ymin'; | |
ALTER FUNCTION public.ymin(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 796 (class 1255 OID 19153) | |
-- Dependencies: 6 1102 | |
-- Name: z(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION z(geometry) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_z_point'; | |
ALTER FUNCTION public.z(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 797 (class 1255 OID 19154) | |
-- Dependencies: 6 1090 | |
-- Name: zmax(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION zmax(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_zmax'; | |
ALTER FUNCTION public.zmax(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 798 (class 1255 OID 19155) | |
-- Dependencies: 6 1102 | |
-- Name: zmflag(geometry); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION zmflag(geometry) RETURNS smallint | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'LWGEOM_zmflag'; | |
ALTER FUNCTION public.zmflag(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 799 (class 1255 OID 19156) | |
-- Dependencies: 6 1090 | |
-- Name: zmin(box3d); Type: FUNCTION; Schema: public; Owner: postgres | |
-- | |
CREATE FUNCTION zmin(box3d) RETURNS double precision | |
LANGUAGE c IMMUTABLE STRICT | |
AS '$libdir/postgis-1.5', 'BOX3D_zmin'; | |
ALTER FUNCTION public.zmin(box3d) OWNER TO postgres; | |
-- | |
-- TOC entry 1175 (class 1255 OID 19157) | |
-- Dependencies: 6 1104 1102 330 329 | |
-- Name: accum(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE accum(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_accum_finalfn | |
); | |
ALTER AGGREGATE public.accum(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1176 (class 1255 OID 19158) | |
-- Dependencies: 6 1102 1102 330 331 | |
-- Name: collect(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE collect(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_collect_finalfn | |
); | |
ALTER AGGREGATE public.collect(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1177 (class 1255 OID 19159) | |
-- Dependencies: 6 1093 1102 500 | |
-- Name: extent(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE extent(geometry) ( | |
SFUNC = public.st_combine_bbox, | |
STYPE = box3d_extent | |
); | |
ALTER AGGREGATE public.extent(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1178 (class 1255 OID 19160) | |
-- Dependencies: 6 1090 1102 124 | |
-- Name: extent3d(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE extent3d(geometry) ( | |
SFUNC = public.combine_bbox, | |
STYPE = box3d | |
); | |
ALTER AGGREGATE public.extent3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1179 (class 1255 OID 19161) | |
-- Dependencies: 6 1102 1102 330 332 | |
-- Name: makeline(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE makeline(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_makeline_finalfn | |
); | |
ALTER AGGREGATE public.makeline(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1180 (class 1255 OID 19162) | |
-- Dependencies: 6 1102 1102 496 | |
-- Name: memcollect(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE memcollect(geometry) ( | |
SFUNC = public.st_collect, | |
STYPE = geometry | |
); | |
ALTER AGGREGATE public.memcollect(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1181 (class 1255 OID 19163) | |
-- Dependencies: 1102 6 1102 231 | |
-- Name: memgeomunion(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE memgeomunion(geometry) ( | |
SFUNC = geomunion, | |
STYPE = geometry | |
); | |
ALTER AGGREGATE public.memgeomunion(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1182 (class 1255 OID 19164) | |
-- Dependencies: 333 6 1102 1102 330 | |
-- Name: polygonize(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE polygonize(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_polygonize_finalfn | |
); | |
ALTER AGGREGATE public.polygonize(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1183 (class 1255 OID 19165) | |
-- Dependencies: 1104 1102 329 330 6 | |
-- Name: st_accum(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_accum(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_accum_finalfn | |
); | |
ALTER AGGREGATE public.st_accum(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1184 (class 1255 OID 19166) | |
-- Dependencies: 330 331 1102 1102 6 | |
-- Name: st_collect(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_collect(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_collect_finalfn | |
); | |
ALTER AGGREGATE public.st_collect(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1185 (class 1255 OID 19167) | |
-- Dependencies: 1102 6 1093 500 | |
-- Name: st_extent(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_extent(geometry) ( | |
SFUNC = public.st_combine_bbox, | |
STYPE = box3d_extent | |
); | |
ALTER AGGREGATE public.st_extent(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1171 (class 1255 OID 19168) | |
-- Dependencies: 1090 6 1102 501 | |
-- Name: st_extent3d(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_extent3d(geometry) ( | |
SFUNC = public.st_combine_bbox, | |
STYPE = box3d | |
); | |
ALTER AGGREGATE public.st_extent3d(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1172 (class 1255 OID 19169) | |
-- Dependencies: 1102 330 332 6 1102 | |
-- Name: st_makeline(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_makeline(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_makeline_finalfn | |
); | |
ALTER AGGREGATE public.st_makeline(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1173 (class 1255 OID 19170) | |
-- Dependencies: 1102 6 496 1102 | |
-- Name: st_memcollect(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_memcollect(geometry) ( | |
SFUNC = public.st_collect, | |
STYPE = geometry | |
); | |
ALTER AGGREGATE public.st_memcollect(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1174 (class 1255 OID 19171) | |
-- Dependencies: 756 6 1102 1102 | |
-- Name: st_memunion(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_memunion(geometry) ( | |
SFUNC = public.st_union, | |
STYPE = geometry | |
); | |
ALTER AGGREGATE public.st_memunion(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1186 (class 1255 OID 19172) | |
-- Dependencies: 1102 6 1102 330 333 | |
-- Name: st_polygonize(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_polygonize(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_polygonize_finalfn | |
); | |
ALTER AGGREGATE public.st_polygonize(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1187 (class 1255 OID 19173) | |
-- Dependencies: 334 330 1102 6 1102 | |
-- Name: st_union(geometry); Type: AGGREGATE; Schema: public; Owner: postgres | |
-- | |
CREATE AGGREGATE st_union(geometry) ( | |
SFUNC = pgis_geometry_accum_transfn, | |
STYPE = pgis_abs, | |
FINALFUNC = pgis_geometry_union_finalfn | |
); | |
ALTER AGGREGATE public.st_union(geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1893 (class 2617 OID 19174) | |
-- Dependencies: 1102 6 207 208 215 1102 | |
-- Name: &&; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR && ( | |
PROCEDURE = geometry_overlap, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = &&, | |
RESTRICT = geometry_gist_sel, | |
JOIN = geometry_gist_joinsel | |
); | |
ALTER OPERATOR public.&& (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1894 (class 2617 OID 19175) | |
-- Dependencies: 1099 6 176 180 185 1099 | |
-- Name: &&; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR && ( | |
PROCEDURE = geography_overlaps, | |
LEFTARG = geography, | |
RIGHTARG = geography, | |
COMMUTATOR = &&, | |
RESTRICT = geography_gist_selectivity, | |
JOIN = geography_gist_join_selectivity | |
); | |
ALTER OPERATOR public.&& (geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 1895 (class 2617 OID 19177) | |
-- Dependencies: 1102 216 6 1102 | |
-- Name: &<; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR &< ( | |
PROCEDURE = geometry_overleft, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = &>, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.&< (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1896 (class 2617 OID 19179) | |
-- Dependencies: 1102 214 6 1102 | |
-- Name: &<|; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR &<| ( | |
PROCEDURE = geometry_overbelow, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = |&>, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.&<| (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1897 (class 2617 OID 19176) | |
-- Dependencies: 6 217 1102 1102 | |
-- Name: &>; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR &> ( | |
PROCEDURE = geometry_overright, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = &<, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.&> (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1898 (class 2617 OID 19182) | |
-- Dependencies: 212 6 1102 1102 | |
-- Name: <; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR < ( | |
PROCEDURE = geometry_lt, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = >, | |
NEGATOR = >=, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.< (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1901 (class 2617 OID 19185) | |
-- Dependencies: 6 184 1099 1099 | |
-- Name: <; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR < ( | |
PROCEDURE = geography_lt, | |
LEFTARG = geography, | |
RIGHTARG = geography, | |
COMMUTATOR = >, | |
NEGATOR = >=, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.< (geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 1902 (class 2617 OID 19187) | |
-- Dependencies: 6 211 1102 1102 | |
-- Name: <<; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR << ( | |
PROCEDURE = geometry_left, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = >>, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.<< (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1903 (class 2617 OID 19189) | |
-- Dependencies: 1102 1102 201 6 | |
-- Name: <<|; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR <<| ( | |
PROCEDURE = geometry_below, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = |>>, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.<<| (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1904 (class 2617 OID 19190) | |
-- Dependencies: 6 210 1102 1102 | |
-- Name: <=; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR <= ( | |
PROCEDURE = geometry_le, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = >=, | |
NEGATOR = >, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.<= (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1905 (class 2617 OID 19191) | |
-- Dependencies: 1099 1099 183 6 | |
-- Name: <=; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR <= ( | |
PROCEDURE = geography_le, | |
LEFTARG = geography, | |
RIGHTARG = geography, | |
COMMUTATOR = >=, | |
NEGATOR = >, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.<= (geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 1906 (class 2617 OID 19192) | |
-- Dependencies: 205 1102 6 1102 | |
-- Name: =; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR = ( | |
PROCEDURE = geometry_eq, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = =, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.= (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1907 (class 2617 OID 19193) | |
-- Dependencies: 171 1099 6 1099 | |
-- Name: =; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR = ( | |
PROCEDURE = geography_eq, | |
LEFTARG = geography, | |
RIGHTARG = geography, | |
COMMUTATOR = =, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.= (geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 1899 (class 2617 OID 19180) | |
-- Dependencies: 1102 209 1102 6 | |
-- Name: >; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR > ( | |
PROCEDURE = geometry_gt, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = <, | |
NEGATOR = <=, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.> (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1908 (class 2617 OID 19183) | |
-- Dependencies: 6 182 1099 1099 | |
-- Name: >; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR > ( | |
PROCEDURE = geography_gt, | |
LEFTARG = geography, | |
RIGHTARG = geography, | |
COMMUTATOR = <, | |
NEGATOR = <=, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.> (geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 1909 (class 2617 OID 19181) | |
-- Dependencies: 6 206 1102 1102 | |
-- Name: >=; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR >= ( | |
PROCEDURE = geometry_ge, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = <=, | |
NEGATOR = <, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.>= (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1910 (class 2617 OID 19184) | |
-- Dependencies: 6 172 1099 1099 | |
-- Name: >=; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR >= ( | |
PROCEDURE = geography_ge, | |
LEFTARG = geography, | |
RIGHTARG = geography, | |
COMMUTATOR = <=, | |
NEGATOR = <, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.>= (geography, geography) OWNER TO postgres; | |
-- | |
-- TOC entry 1911 (class 2617 OID 19186) | |
-- Dependencies: 1102 1102 218 6 | |
-- Name: >>; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR >> ( | |
PROCEDURE = geometry_right, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = <<, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.>> (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1912 (class 2617 OID 19195) | |
-- Dependencies: 6 204 1102 1102 | |
-- Name: @; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR @ ( | |
PROCEDURE = geometry_contained, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = ~, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.@ (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1900 (class 2617 OID 19178) | |
-- Dependencies: 6 1102 213 1102 | |
-- Name: |&>; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR |&> ( | |
PROCEDURE = geometry_overabove, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = &<|, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.|&> (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1913 (class 2617 OID 19188) | |
-- Dependencies: 200 6 1102 1102 | |
-- Name: |>>; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR |>> ( | |
PROCEDURE = geometry_above, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = <<|, | |
RESTRICT = positionsel, | |
JOIN = positionjoinsel | |
); | |
ALTER OPERATOR public.|>> (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1914 (class 2617 OID 19194) | |
-- Dependencies: 203 1102 1102 6 | |
-- Name: ~; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR ~ ( | |
PROCEDURE = geometry_contain, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = @, | |
RESTRICT = contsel, | |
JOIN = contjoinsel | |
); | |
ALTER OPERATOR public.~ (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 1915 (class 2617 OID 19196) | |
-- Dependencies: 6 1102 1102 220 | |
-- Name: ~=; Type: OPERATOR; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR ~= ( | |
PROCEDURE = geometry_samebox, | |
LEFTARG = geometry, | |
RIGHTARG = geometry, | |
COMMUTATOR = ~=, | |
RESTRICT = eqsel, | |
JOIN = eqjoinsel | |
); | |
ALTER OPERATOR public.~= (geometry, geometry) OWNER TO postgres; | |
-- | |
-- TOC entry 2028 (class 2616 OID 19198) | |
-- Dependencies: 6 1099 2139 | |
-- Name: btree_geography_ops; Type: OPERATOR CLASS; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR CLASS btree_geography_ops | |
DEFAULT FOR TYPE geography USING btree AS | |
OPERATOR 1 <(geography,geography) , | |
OPERATOR 2 <=(geography,geography) , | |
OPERATOR 3 =(geography,geography) , | |
OPERATOR 4 >=(geography,geography) , | |
OPERATOR 5 >(geography,geography) , | |
FUNCTION 1 geography_cmp(geography,geography); | |
ALTER OPERATOR CLASS public.btree_geography_ops USING btree OWNER TO postgres; | |
-- | |
-- TOC entry 2029 (class 2616 OID 19206) | |
-- Dependencies: 6 1102 2140 | |
-- Name: btree_geometry_ops; Type: OPERATOR CLASS; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR CLASS btree_geometry_ops | |
DEFAULT FOR TYPE geometry USING btree AS | |
OPERATOR 1 <(geometry,geometry) , | |
OPERATOR 2 <=(geometry,geometry) , | |
OPERATOR 3 =(geometry,geometry) , | |
OPERATOR 4 >=(geometry,geometry) , | |
OPERATOR 5 >(geometry,geometry) , | |
FUNCTION 1 geometry_cmp(geometry,geometry); | |
ALTER OPERATOR CLASS public.btree_geometry_ops USING btree OWNER TO postgres; | |
-- | |
-- TOC entry 2030 (class 2616 OID 19214) | |
-- Dependencies: 2141 6 1107 1099 | |
-- Name: gist_geography_ops; Type: OPERATOR CLASS; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR CLASS gist_geography_ops | |
DEFAULT FOR TYPE geography USING gist AS | |
STORAGE gidx , | |
OPERATOR 3 &&(geography,geography) , | |
FUNCTION 1 geography_gist_consistent(internal,geometry,integer) , | |
FUNCTION 2 geography_gist_union(bytea,internal) , | |
FUNCTION 3 geography_gist_compress(internal) , | |
FUNCTION 4 geography_gist_decompress(internal) , | |
FUNCTION 5 geography_gist_penalty(internal,internal,internal) , | |
FUNCTION 6 geography_gist_picksplit(internal,internal) , | |
FUNCTION 7 geography_gist_same(box2d,box2d,internal); | |
ALTER OPERATOR CLASS public.gist_geography_ops USING gist OWNER TO postgres; | |
-- | |
-- TOC entry 2031 (class 2616 OID 19224) | |
-- Dependencies: 1102 6 2142 1087 | |
-- Name: gist_geometry_ops; Type: OPERATOR CLASS; Schema: public; Owner: postgres | |
-- | |
CREATE OPERATOR CLASS gist_geometry_ops | |
DEFAULT FOR TYPE geometry USING gist AS | |
STORAGE box2d , | |
OPERATOR 1 <<(geometry,geometry) , | |
OPERATOR 2 &<(geometry,geometry) , | |
OPERATOR 3 &&(geometry,geometry) , | |
OPERATOR 4 &>(geometry,geometry) , | |
OPERATOR 5 >>(geometry,geometry) , | |
OPERATOR 6 ~=(geometry,geometry) , | |
OPERATOR 7 ~(geometry,geometry) , | |
OPERATOR 8 @(geometry,geometry) , | |
OPERATOR 9 &<|(geometry,geometry) , | |
OPERATOR 10 <<|(geometry,geometry) , | |
OPERATOR 11 |>>(geometry,geometry) , | |
OPERATOR 12 |&>(geometry,geometry) , | |
FUNCTION 1 lwgeom_gist_consistent(internal,geometry,integer) , | |
FUNCTION 2 lwgeom_gist_union(bytea,internal) , | |
FUNCTION 3 lwgeom_gist_compress(internal) , | |
FUNCTION 4 lwgeom_gist_decompress(internal) , | |
FUNCTION 5 lwgeom_gist_penalty(internal,internal,internal) , | |
FUNCTION 6 lwgeom_gist_picksplit(internal,internal) , | |
FUNCTION 7 lwgeom_gist_same(box2d,box2d,internal); | |
ALTER OPERATOR CLASS public.gist_geometry_ops USING gist OWNER TO postgres; | |
SET search_path = pg_catalog; | |
-- | |
-- TOC entry 2712 (class 2605 OID 19244) | |
-- Dependencies: 110 110 1087 1090 | |
-- Name: CAST (public.box2d AS public.box3d); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box2d AS public.box3d) WITH FUNCTION public.box3d(public.box2d) AS IMPLICIT; | |
-- | |
-- TOC entry 2713 (class 2605 OID 19245) | |
-- Dependencies: 194 1102 1087 194 | |
-- Name: CAST (public.box2d AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box2d AS public.geometry) WITH FUNCTION public.geometry(public.box2d) AS IMPLICIT; | |
-- | |
-- TOC entry 2714 (class 2605 OID 19246) | |
-- Dependencies: 105 1090 105 | |
-- Name: CAST (public.box3d AS box); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box3d AS box) WITH FUNCTION public.box(public.box3d) AS IMPLICIT; | |
-- | |
-- TOC entry 2715 (class 2605 OID 19247) | |
-- Dependencies: 108 108 1087 1090 | |
-- Name: CAST (public.box3d AS public.box2d); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box3d AS public.box2d) WITH FUNCTION public.box2d(public.box3d) AS IMPLICIT; | |
-- | |
-- TOC entry 2716 (class 2605 OID 19248) | |
-- Dependencies: 195 1090 1102 195 | |
-- Name: CAST (public.box3d AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box3d AS public.geometry) WITH FUNCTION public.geometry(public.box3d) AS IMPLICIT; | |
-- | |
-- TOC entry 2717 (class 2605 OID 19249) | |
-- Dependencies: 106 106 1087 1093 | |
-- Name: CAST (public.box3d_extent AS public.box2d); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box3d_extent AS public.box2d) WITH FUNCTION public.box2d(public.box3d_extent) AS IMPLICIT; | |
-- | |
-- TOC entry 2718 (class 2605 OID 19250) | |
-- Dependencies: 111 1093 1090 111 | |
-- Name: CAST (public.box3d_extent AS public.box3d); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box3d_extent AS public.box3d) WITH FUNCTION public.box3d_extent(public.box3d_extent) AS IMPLICIT; | |
-- | |
-- TOC entry 2719 (class 2605 OID 19251) | |
-- Dependencies: 193 1093 193 1102 | |
-- Name: CAST (public.box3d_extent AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.box3d_extent AS public.geometry) WITH FUNCTION public.geometry(public.box3d_extent) AS IMPLICIT; | |
-- | |
-- TOC entry 2523 (class 2605 OID 19252) | |
-- Dependencies: 198 1102 198 | |
-- Name: CAST (bytea AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (bytea AS public.geometry) WITH FUNCTION public.geometry(bytea) AS IMPLICIT; | |
-- | |
-- TOC entry 2720 (class 2605 OID 19253) | |
-- Dependencies: 197 197 1096 1102 | |
-- Name: CAST (public.chip AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.chip AS public.geometry) WITH FUNCTION public.geometry(public.chip) AS IMPLICIT; | |
-- | |
-- TOC entry 2721 (class 2605 OID 19254) | |
-- Dependencies: 168 1099 1099 168 | |
-- Name: CAST (public.geography AS public.geography); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geography AS public.geography) WITH FUNCTION public.geography(public.geography, integer, boolean) AS IMPLICIT; | |
-- | |
-- TOC entry 2722 (class 2605 OID 19255) | |
-- Dependencies: 199 199 1099 1102 | |
-- Name: CAST (public.geography AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geography AS public.geometry) WITH FUNCTION public.geometry(public.geography); | |
-- | |
-- TOC entry 2725 (class 2605 OID 19256) | |
-- Dependencies: 104 104 1102 | |
-- Name: CAST (public.geometry AS box); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geometry AS box) WITH FUNCTION public.box(public.geometry) AS IMPLICIT; | |
-- | |
-- TOC entry 2726 (class 2605 OID 19257) | |
-- Dependencies: 107 107 1102 1087 | |
-- Name: CAST (public.geometry AS public.box2d); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geometry AS public.box2d) WITH FUNCTION public.box2d(public.geometry) AS IMPLICIT; | |
-- | |
-- TOC entry 2727 (class 2605 OID 19258) | |
-- Dependencies: 109 1090 109 1102 | |
-- Name: CAST (public.geometry AS public.box3d); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geometry AS public.box3d) WITH FUNCTION public.box3d(public.geometry) AS IMPLICIT; | |
-- | |
-- TOC entry 2723 (class 2605 OID 19259) | |
-- Dependencies: 116 116 1102 | |
-- Name: CAST (public.geometry AS bytea); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geometry AS bytea) WITH FUNCTION public.bytea(public.geometry) AS IMPLICIT; | |
-- | |
-- TOC entry 2728 (class 2605 OID 19260) | |
-- Dependencies: 169 1102 169 1099 | |
-- Name: CAST (public.geometry AS public.geography); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geometry AS public.geography) WITH FUNCTION public.geography(public.geometry) AS IMPLICIT; | |
-- | |
-- TOC entry 2724 (class 2605 OID 19261) | |
-- Dependencies: 777 777 1102 | |
-- Name: CAST (public.geometry AS text); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (public.geometry AS text) WITH FUNCTION public.text(public.geometry) AS IMPLICIT; | |
-- | |
-- TOC entry 2589 (class 2605 OID 19262) | |
-- Dependencies: 196 196 1102 | |
-- Name: CAST (text AS public.geometry); Type: CAST; Schema: pg_catalog; Owner: | |
-- | |
CREATE CAST (text AS public.geometry) WITH FUNCTION public.geometry(text) AS IMPLICIT; | |
SET search_path = public, pg_catalog; | |
SET default_tablespace = ''; | |
SET default_with_oids = false; | |
-- | |
-- TOC entry 2411 (class 1259 OID 19263) | |
-- Dependencies: 6 | |
-- Name: agency; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE agency ( | |
agency_url text, | |
agency_name text, | |
agency_timezone text, | |
agency_id integer NOT NULL | |
); | |
ALTER TABLE public.agency OWNER TO postgres; | |
-- | |
-- TOC entry 2412 (class 1259 OID 19269) | |
-- Dependencies: 6 | |
-- Name: calendar; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE calendar ( | |
service_id text NOT NULL, | |
start_date text, | |
end_date text, | |
monday integer, | |
tuesday integer, | |
wednesday integer, | |
thursday integer, | |
friday integer, | |
saturday integer, | |
sunday integer | |
); | |
ALTER TABLE public.calendar OWNER TO postgres; | |
-- | |
-- TOC entry 2413 (class 1259 OID 19275) | |
-- Dependencies: 6 | |
-- Name: calendar_dates; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE calendar_dates ( | |
service_id text NOT NULL, | |
date text NOT NULL, | |
exception_type text | |
); | |
ALTER TABLE public.calendar_dates OWNER TO postgres; | |
-- | |
-- TOC entry 2414 (class 1259 OID 19281) | |
-- Dependencies: 2518 6 | |
-- Name: geography_columns; Type: VIEW; Schema: public; Owner: postgres | |
-- | |
CREATE VIEW geography_columns AS | |
SELECT current_database() AS f_table_catalog, n.nspname AS f_table_schema, c.relname AS f_table_name, a.attname AS f_geography_column, geography_typmod_dims(a.atttypmod) AS coord_dimension, geography_typmod_srid(a.atttypmod) AS srid, geography_typmod_type(a.atttypmod) AS type FROM pg_class c, pg_attribute a, pg_type t, pg_namespace n WHERE ((((((c.relkind = ANY (ARRAY['r'::"char", 'v'::"char"])) AND (t.typname = 'geography'::name)) AND (a.attisdropped = false)) AND (a.atttypid = t.oid)) AND (a.attrelid = c.oid)) AND (c.relnamespace = n.oid)); | |
ALTER TABLE public.geography_columns OWNER TO postgres; | |
SET default_with_oids = true; | |
-- | |
-- TOC entry 2415 (class 1259 OID 19286) | |
-- Dependencies: 6 | |
-- Name: geometry_columns; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE geometry_columns ( | |
f_table_catalog character varying(256) NOT NULL, | |
f_table_schema character varying(256) NOT NULL, | |
f_table_name character varying(256) NOT NULL, | |
f_geometry_column character varying(256) NOT NULL, | |
coord_dimension integer NOT NULL, | |
srid integer NOT NULL, | |
type character varying(30) NOT NULL | |
); | |
ALTER TABLE public.geometry_columns OWNER TO postgres; | |
SET default_with_oids = false; | |
-- | |
-- TOC entry 2416 (class 1259 OID 19292) | |
-- Dependencies: 6 | |
-- Name: myway_observations; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE myway_observations ( | |
observation_id text NOT NULL, | |
myway_stop text, | |
"time" timestamp with time zone, | |
myway_route text | |
); | |
ALTER TABLE public.myway_observations OWNER TO postgres; | |
-- | |
-- TOC entry 2417 (class 1259 OID 19298) | |
-- Dependencies: 6 | |
-- Name: myway_routes; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE myway_routes ( | |
myway_route text NOT NULL, | |
route_full_name text | |
); | |
ALTER TABLE public.myway_routes OWNER TO postgres; | |
-- | |
-- TOC entry 2418 (class 1259 OID 19304) | |
-- Dependencies: 6 2417 | |
-- Name: myway_routes_myway_route_seq; Type: SEQUENCE; Schema: public; Owner: postgres | |
-- | |
CREATE SEQUENCE myway_routes_myway_route_seq | |
START WITH 1 | |
INCREMENT BY 1 | |
NO MINVALUE | |
NO MAXVALUE | |
CACHE 1; | |
ALTER TABLE public.myway_routes_myway_route_seq OWNER TO postgres; | |
-- | |
-- TOC entry 2775 (class 0 OID 0) | |
-- Dependencies: 2418 | |
-- Name: myway_routes_myway_route_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres | |
-- | |
ALTER SEQUENCE myway_routes_myway_route_seq OWNED BY myway_routes.myway_route; | |
-- | |
-- TOC entry 2419 (class 1259 OID 19306) | |
-- Dependencies: 2417 6 | |
-- Name: myway_routes_route_full_name_seq; Type: SEQUENCE; Schema: public; Owner: postgres | |
-- | |
CREATE SEQUENCE myway_routes_route_full_name_seq | |
START WITH 1 | |
INCREMENT BY 1 | |
NO MINVALUE | |
NO MAXVALUE | |
CACHE 1; | |
ALTER TABLE public.myway_routes_route_full_name_seq OWNER TO postgres; | |
-- | |
-- TOC entry 2776 (class 0 OID 0) | |
-- Dependencies: 2419 | |
-- Name: myway_routes_route_full_name_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres | |
-- | |
ALTER SEQUENCE myway_routes_route_full_name_seq OWNED BY myway_routes.route_full_name; | |
-- | |
-- TOC entry 2420 (class 1259 OID 19308) | |
-- Dependencies: 6 | |
-- Name: myway_stops; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE myway_stops ( | |
myway_stop text NOT NULL, | |
stop_code text, | |
stop_street text | |
); | |
ALTER TABLE public.myway_stops OWNER TO postgres; | |
-- | |
-- TOC entry 2421 (class 1259 OID 19314) | |
-- Dependencies: 6 | |
-- Name: myway_timingdeltas; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE myway_timingdeltas ( | |
observation_id text NOT NULL, | |
route_full_name text, | |
stop_code text, | |
timing_delta integer, | |
"time" time with time zone, | |
date date, | |
timing_period text, | |
stop_sequence integer | |
); | |
ALTER TABLE public.myway_timingdeltas OWNER TO postgres; | |
-- | |
-- TOC entry 2422 (class 1259 OID 19320) | |
-- Dependencies: 6 2421 | |
-- Name: myway_timingdeltas_timing_period_seq; Type: SEQUENCE; Schema: public; Owner: postgres | |
-- | |
CREATE SEQUENCE myway_timingdeltas_timing_period_seq | |
START WITH 1 | |
INCREMENT BY 1 | |
NO MINVALUE | |
NO MAXVALUE | |
CACHE 1; | |
ALTER TABLE public.myway_timingdeltas_timing_period_seq OWNER TO postgres; | |
-- | |
-- TOC entry 2777 (class 0 OID 0) | |
-- Dependencies: 2422 | |
-- Name: myway_timingdeltas_timing_period_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres | |
-- | |
ALTER SEQUENCE myway_timingdeltas_timing_period_seq OWNED BY myway_timingdeltas.timing_period; | |
-- | |
-- TOC entry 2423 (class 1259 OID 19322) | |
-- Dependencies: 6 | |
-- Name: routes; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE routes ( | |
route_type integer, | |
route_id integer NOT NULL, | |
route_short_name text, | |
route_long_name text, | |
agency_id integer, | |
route_url text, | |
route_color text, | |
route_text_color text | |
); | |
ALTER TABLE public.routes OWNER TO postgres; | |
-- | |
-- TOC entry 2424 (class 1259 OID 19328) | |
-- Dependencies: 6 | |
-- Name: servicealerts_alerts; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE servicealerts_alerts ( | |
id integer NOT NULL, | |
url text, | |
description text, | |
start timestamp with time zone, | |
"end" timestamp with time zone | |
); | |
ALTER TABLE public.servicealerts_alerts OWNER TO postgres; | |
-- | |
-- TOC entry 2425 (class 1259 OID 19334) | |
-- Dependencies: 6 2424 | |
-- Name: servicealerts_alerts_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres | |
-- | |
CREATE SEQUENCE servicealerts_alerts_id_seq | |
START WITH 1 | |
INCREMENT BY 1 | |
NO MINVALUE | |
NO MAXVALUE | |
CACHE 1; | |
ALTER TABLE public.servicealerts_alerts_id_seq OWNER TO postgres; | |
-- | |
-- TOC entry 2778 (class 0 OID 0) | |
-- Dependencies: 2425 | |
-- Name: servicealerts_alerts_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres | |
-- | |
ALTER SEQUENCE servicealerts_alerts_id_seq OWNED BY servicealerts_alerts.id; | |
-- | |
-- TOC entry 2426 (class 1259 OID 19336) | |
-- Dependencies: 6 | |
-- Name: servicealerts_informed; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE servicealerts_informed ( | |
servicealert_id integer NOT NULL, | |
informed_class text NOT NULL, | |
informed_id text NOT NULL, | |
informed_action text | |
); | |
ALTER TABLE public.servicealerts_informed OWNER TO postgres; | |
-- | |
-- TOC entry 2427 (class 1259 OID 19342) | |
-- Dependencies: 6 | |
-- Name: shapes; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE shapes ( | |
shape_id text NOT NULL, | |
shape_pt_lat double precision, | |
shape_pt_lon double precision, | |
shape_pt_sequence integer NOT NULL, | |
shape_dist_traveled integer | |
); | |
ALTER TABLE public.shapes OWNER TO postgres; | |
-- | |
-- TOC entry 2428 (class 1259 OID 19348) | |
-- Dependencies: 6 | |
-- Name: spatial_ref_sys; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE spatial_ref_sys ( | |
srid integer NOT NULL, | |
auth_name character varying(256), | |
auth_srid integer, | |
srtext character varying(2048), | |
proj4text character varying(2048) | |
); | |
ALTER TABLE public.spatial_ref_sys OWNER TO postgres; | |
-- | |
-- TOC entry 2431 (class 1259 OID 20682) | |
-- Dependencies: 6 | |
-- Name: stop_times; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE stop_times ( | |
trip_id integer NOT NULL, | |
arrival_time time without time zone, | |
departure_time time without time zone, | |
stop_id integer, | |
stop_sequence integer NOT NULL, | |
stop_headsign text, | |
pickup_type text, | |
drop_off_type text, | |
shape_dist_travelled text | |
); | |
ALTER TABLE public.stop_times OWNER TO postgres; | |
-- | |
-- TOC entry 2429 (class 1259 OID 19360) | |
-- Dependencies: 6 1099 | |
-- Name: stops; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE stops ( | |
stop_lat double precision, | |
stop_code text, | |
stop_lon double precision, | |
stop_id integer NOT NULL, | |
stop_name text, | |
zone_id text, | |
"position" geography | |
); | |
ALTER TABLE public.stops OWNER TO postgres; | |
-- | |
-- TOC entry 2430 (class 1259 OID 19366) | |
-- Dependencies: 6 | |
-- Name: trips; Type: TABLE; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE TABLE trips ( | |
route_id integer, | |
trip_id integer NOT NULL, | |
trip_headsign text, | |
service_id text, | |
shape_id text | |
); | |
ALTER TABLE public.trips OWNER TO postgres; | |
-- | |
-- TOC entry 2729 (class 2604 OID 19372) | |
-- Dependencies: 2425 2424 | |
-- Name: id; Type: DEFAULT; Schema: public; Owner: postgres | |
-- | |
ALTER TABLE servicealerts_alerts ALTER COLUMN id SET DEFAULT nextval('servicealerts_alerts_id_seq'::regclass); | |
-- | |
-- TOC entry 2731 (class 2606 OID 19374) | |
-- Dependencies: 2411 2411 | |
-- Name: agency_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY agency | |
ADD CONSTRAINT agency_pkey PRIMARY KEY (agency_id); | |
-- | |
-- TOC entry 2735 (class 2606 OID 19376) | |
-- Dependencies: 2413 2413 2413 | |
-- Name: calendar_dates_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY calendar_dates | |
ADD CONSTRAINT calendar_dates_pkey PRIMARY KEY (service_id, date); | |
-- | |
-- TOC entry 2733 (class 2606 OID 19378) | |
-- Dependencies: 2412 2412 | |
-- Name: calendar_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY calendar | |
ADD CONSTRAINT calendar_pkey PRIMARY KEY (service_id); | |
-- | |
-- TOC entry 2737 (class 2606 OID 19380) | |
-- Dependencies: 2415 2415 2415 2415 2415 | |
-- Name: geometry_columns_pk; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY geometry_columns | |
ADD CONSTRAINT geometry_columns_pk PRIMARY KEY (f_table_catalog, f_table_schema, f_table_name, f_geometry_column); | |
-- | |
-- TOC entry 2739 (class 2606 OID 19382) | |
-- Dependencies: 2416 2416 | |
-- Name: myway_observations_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY myway_observations | |
ADD CONSTRAINT myway_observations_pkey PRIMARY KEY (observation_id); | |
-- | |
-- TOC entry 2741 (class 2606 OID 19384) | |
-- Dependencies: 2417 2417 | |
-- Name: myway_routes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY myway_routes | |
ADD CONSTRAINT myway_routes_pkey PRIMARY KEY (myway_route); | |
-- | |
-- TOC entry 2745 (class 2606 OID 19386) | |
-- Dependencies: 2421 2421 | |
-- Name: myway_timingdeltas_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY myway_timingdeltas | |
ADD CONSTRAINT myway_timingdeltas_pkey PRIMARY KEY (observation_id); | |
-- | |
-- TOC entry 2743 (class 2606 OID 19388) | |
-- Dependencies: 2420 2420 | |
-- Name: mywaystops_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY myway_stops | |
ADD CONSTRAINT mywaystops_pkey PRIMARY KEY (myway_stop); | |
-- | |
-- TOC entry 2748 (class 2606 OID 19390) | |
-- Dependencies: 2423 2423 | |
-- Name: routes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY routes | |
ADD CONSTRAINT routes_pkey PRIMARY KEY (route_id); | |
-- | |
-- TOC entry 2750 (class 2606 OID 19392) | |
-- Dependencies: 2424 2424 | |
-- Name: servicealerts_alerts_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY servicealerts_alerts | |
ADD CONSTRAINT servicealerts_alerts_pkey PRIMARY KEY (id); | |
-- | |
-- TOC entry 2752 (class 2606 OID 19394) | |
-- Dependencies: 2426 2426 2426 2426 | |
-- Name: servicealerts_informed_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY servicealerts_informed | |
ADD CONSTRAINT servicealerts_informed_pkey PRIMARY KEY (servicealert_id, informed_class, informed_id); | |
-- | |
-- TOC entry 2754 (class 2606 OID 19396) | |
-- Dependencies: 2427 2427 2427 | |
-- Name: shapes_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY shapes | |
ADD CONSTRAINT shapes_pkey PRIMARY KEY (shape_id, shape_pt_sequence); | |
-- | |
-- TOC entry 2756 (class 2606 OID 19398) | |
-- Dependencies: 2428 2428 | |
-- Name: spatial_ref_sys_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY spatial_ref_sys | |
ADD CONSTRAINT spatial_ref_sys_pkey PRIMARY KEY (srid); | |
-- | |
-- TOC entry 2766 (class 2606 OID 20689) | |
-- Dependencies: 2431 2431 2431 | |
-- Name: stop_times_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY stop_times | |
ADD CONSTRAINT stop_times_pkey PRIMARY KEY (trip_id, stop_sequence); | |
-- | |
-- TOC entry 2758 (class 2606 OID 19402) | |
-- Dependencies: 2429 2429 | |
-- Name: stops_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY stops | |
ADD CONSTRAINT stops_pkey PRIMARY KEY (stop_id); | |
-- | |
-- TOC entry 2760 (class 2606 OID 19404) | |
-- Dependencies: 2429 2429 | |
-- Name: stops_stop_code_key; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY stops | |
ADD CONSTRAINT stops_stop_code_key UNIQUE (stop_code); | |
-- | |
-- TOC entry 2763 (class 2606 OID 19406) | |
-- Dependencies: 2430 2430 | |
-- Name: trips_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres; Tablespace: | |
-- | |
ALTER TABLE ONLY trips | |
ADD CONSTRAINT trips_pkey PRIMARY KEY (trip_id); | |
-- | |
-- TOC entry 2746 (class 1259 OID 19407) | |
-- Dependencies: 2423 | |
-- Name: routenumber; Type: INDEX; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE INDEX routenumber ON routes USING btree (route_short_name); | |
-- | |
-- TOC entry 2761 (class 1259 OID 19408) | |
-- Dependencies: 2430 | |
-- Name: routetrips; Type: INDEX; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE INDEX routetrips ON trips USING btree (route_id); | |
-- | |
-- TOC entry 2764 (class 1259 OID 20690) | |
-- Dependencies: 2431 2431 2431 | |
-- Name: starttime; Type: INDEX; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE UNIQUE INDEX starttime ON stop_times USING btree (trip_id, stop_id, stop_sequence); | |
-- | |
-- TOC entry 2767 (class 1259 OID 20691) | |
-- Dependencies: 2431 2431 | |
-- Name: stoptimes; Type: INDEX; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE INDEX stoptimes ON stop_times USING btree (arrival_time, stop_id); | |
-- | |
-- TOC entry 2768 (class 1259 OID 20692) | |
-- Dependencies: 2431 2431 | |
-- Name: triptimes; Type: INDEX; Schema: public; Owner: postgres; Tablespace: | |
-- | |
CREATE INDEX triptimes ON stop_times USING btree (trip_id, arrival_time); | |
-- | |
-- TOC entry 2769 (class 2606 OID 19412) | |
-- Dependencies: 2426 2749 2424 | |
-- Name: servicealerts_alertid; Type: FK CONSTRAINT; Schema: public; Owner: postgres | |
-- | |
ALTER TABLE ONLY servicealerts_informed | |
ADD CONSTRAINT servicealerts_alertid FOREIGN KEY (servicealert_id) REFERENCES servicealerts_alerts(id); | |
-- | |
-- TOC entry 2774 (class 0 OID 0) | |
-- Dependencies: 6 | |
-- Name: public; Type: ACL; Schema: -; Owner: postgres | |
-- | |
REVOKE ALL ON SCHEMA public FROM PUBLIC; | |
REVOKE ALL ON SCHEMA public FROM postgres; | |
GRANT ALL ON SCHEMA public TO postgres; | |
GRANT ALL ON SCHEMA public TO PUBLIC; | |
-- Completed on 2011-10-07 22:30:11 | |
-- | |
-- PostgreSQL database dump complete | |
-- | |
/*! | |
* jQuery Mobile v1.0b2 | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* A | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-a { | |
border: 1px solid #2A2A2A; | |
background: #111111; | |
color: #ffffff; | |
font-weight: bold; | |
text-shadow: 0 -1px 1px #000000; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#111)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #3c3c3c, #111); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #3c3c3c, #111); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #3c3c3c, #111); /* IE10 */ | |
background-image: -o-linear-gradient(top, #3c3c3c, #111); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #3c3c3c, #111); | |
} | |
.ui-bar-a, | |
.ui-bar-a input, | |
.ui-bar-a select, | |
.ui-bar-a textarea, | |
.ui-bar-a button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-bar-a .ui-link-inherit { | |
color: #fff; | |
} | |
.ui-bar-a .ui-link { | |
color: #7cc4e7; | |
font-weight: bold; | |
} | |
.ui-body-a { | |
border: 1px solid #2A2A2A; | |
background: #222222; | |
color: #fff; | |
text-shadow: 0 1px 0 #000; | |
font-weight: normal; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#666), to(#222)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #666, #222); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #666, #222); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #666, #222); /* IE10 */ | |
background-image: -o-linear-gradient(top, #666, #222); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #666, #222); | |
} | |
.ui-body-a, | |
.ui-body-a input, | |
.ui-body-a select, | |
.ui-body-a textarea, | |
.ui-body-a button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-body-a .ui-link-inherit { | |
color: #fff; | |
} | |
.ui-body-a .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-br { | |
border-bottom: rgb(130,130,130); | |
border-bottom: rgba(130,130,130,.3); | |
border-bottom-width: 1px; | |
border-bottom-style: solid; | |
} | |
.ui-btn-up-a { | |
border: 1px solid #222; | |
background: #333333; | |
font-weight: bold; | |
color: #fff; | |
text-shadow: 0 -1px 1px #000; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#555), to(#333)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #555, #333); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #555, #333); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #555, #333); /* IE10 */ | |
background-image: -o-linear-gradient(top, #555, #333); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #555, #333); | |
} | |
.ui-btn-up-a a.ui-link-inherit { | |
color: #fff; | |
} | |
.ui-btn-hover-a { | |
border: 1px solid #000; | |
background: #444444; | |
font-weight: bold; | |
color: #fff; | |
text-shadow: 0 -1px 1px #000; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#666), to(#444)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #666, #444); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #666, #444); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #666, #444); /* IE10 */ | |
background-image: -o-linear-gradient(top, #666, #444); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #666, #444); | |
} | |
.ui-btn-hover-a a.ui-link-inherit { | |
color: #fff; | |
} | |
.ui-btn-down-a { | |
border: 1px solid #000; | |
background: #3d3d3d; | |
font-weight: bold; | |
color: #fff; | |
text-shadow: 0 -1px 1px #000; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#333), to(#5a5a5a)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #333, #5a5a5a); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #333, #5a5a5a); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #333, #5a5a5a); /* IE10 */ | |
background-image: -o-linear-gradient(top, #333, #5a5a5a); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #333, #5a5a5a); | |
} | |
.ui-btn-down-a a.ui-link-inherit { | |
color: #fff; | |
} | |
.ui-btn-up-a, | |
.ui-btn-hover-a, | |
.ui-btn-down-a { | |
font-family: Helvetica, Arial, sans-serif; | |
text-decoration: none; | |
} | |
/* B | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-b { | |
border: 1px solid #456f9a; | |
background: #5e87b0; | |
color: #fff; | |
font-weight: bold; | |
text-shadow: 0 -1px 1px #254f7a; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#81a8ce), to(#5e87b0)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #81a8ce, #5e87b0); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #81a8ce, #5e87b0); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #81a8ce, #5e87b0); /* IE10 */ | |
background-image: -o-linear-gradient(top, #81a8ce, #5e87b0); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #81a8ce, #5e87b0); | |
} | |
.ui-bar-b, | |
.ui-bar-b input, | |
.ui-bar-b select, | |
.ui-bar-b textarea, | |
.ui-bar-b button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-bar-b .ui-link-inherit { | |
color: #fff; | |
} | |
.ui-bar-b .ui-link { | |
color: #7cc4e7; | |
font-weight: bold; | |
} | |
.ui-body-b { | |
border: 1px solid #C6C6C6; | |
background: #cccccc; | |
color: #333333; | |
text-shadow: 0 1px 0 #fff; | |
font-weight: normal; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#e6e6e6), to(#ccc)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #e6e6e6, #ccc); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #e6e6e6, #ccc); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #e6e6e6, #ccc); /* IE10 */ | |
background-image: -o-linear-gradient(top, #e6e6e6, #ccc); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #e6e6e6, #ccc); | |
} | |
.ui-body-b, | |
.ui-body-b input, | |
.ui-body-b select, | |
.ui-body-b textarea, | |
.ui-body-b button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-body-b .ui-link-inherit { | |
color: #333333; | |
} | |
.ui-body-b .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-btn-up-b { | |
border: 1px solid #145072; | |
background: #2567ab; | |
font-weight: bold; | |
color: #fff; | |
text-shadow: 0 -1px 1px #145072; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#5f9cc5), to(#396b9e)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #5f9cc5, #396b9e); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #5f9cc5, #396b9e); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #5f9cc5, #396b9e); /* IE10 */ | |
background-image: -o-linear-gradient(top, #5f9cc5, #396b9e); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #5f9cc5, #396b9e); | |
} | |
.ui-btn-up-b a.ui-link-inherit { | |
color: #fff; | |
} | |
.ui-btn-hover-b { | |
border: 1px solid #00516e; | |
background: #4b88b6; | |
font-weight: bold; | |
color: #fff; | |
text-shadow: 0 -1px 1px #014D68; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#72b0d4), to(#4b88b6)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #72b0d4, #4b88b6); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #72b0d4, #4b88b6); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #72b0d4, #4b88b6); /* IE10 */ | |
background-image: -o-linear-gradient(top, #72b0d4, #4b88b6); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #72b0d4, #4b88b6); | |
} | |
.ui-btn-hover-b a.ui-link-inherit { | |
color: #fff; | |
} | |
.ui-btn-down-b { | |
border: 1px solid #225377; | |
background: #4e89c5; | |
font-weight: bold; | |
color: #fff; | |
text-shadow: 0 -1px 1px #225377; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#396b9e), to(#4e89c5)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #396b9e, #4e89c5); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #396b9e, #4e89c5); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #396b9e, #4e89c5); /* IE10 */ | |
background-image: -o-linear-gradient(top, #396b9e, #4e89c5); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #396b9e, #4e89c5); | |
} | |
.ui-btn-down-b a.ui-link-inherit { | |
color: #fff; | |
} | |
.ui-btn-up-b, | |
.ui-btn-hover-b, | |
.ui-btn-down-b { | |
font-family: Helvetica, Arial, sans-serif; | |
text-decoration: none; | |
} | |
/* C | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-c { | |
border: 1px solid #B3B3B3; | |
background: #e9eaeb; | |
color: #3E3E3E; | |
font-weight: bold; | |
text-shadow: 0 1px 1px #fff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0), to(#e9eaeb)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #f0f0f0, #e9eaeb); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #f0f0f0, #e9eaeb); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #f0f0f0, #e9eaeb); /* IE10 */ | |
background-image: -o-linear-gradient(top, #f0f0f0, #e9eaeb); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #f0f0f0, #e9eaeb); | |
} | |
.ui-bar-c, | |
.ui-bar-c input, | |
.ui-bar-c select, | |
.ui-bar-c textarea, | |
.ui-bar-c button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-body-c { | |
border: 1px solid #B3B3B3; | |
color: #333333; | |
text-shadow: 0 1px 0 #fff; | |
background: #f0f0f0; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#ddd)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #eee, #ddd); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #eee, #ddd); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #eee, #ddd); /* IE10 */ | |
background-image: -o-linear-gradient(top, #eee, #ddd); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #eee, #ddd); | |
} | |
.ui-body-c, | |
.ui-body-c input, | |
.ui-body-c select, | |
.ui-body-c textarea, | |
.ui-body-c button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-body-c .ui-link-inherit { | |
color: #333333; | |
} | |
.ui-body-c .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-btn-up-c { | |
border: 1px solid #ccc; | |
background: #eee; | |
font-weight: bold; | |
color: #444; | |
text-shadow: 0 1px 1px #f6f6f6; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#eee)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fdfdfd, #eee); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fdfdfd, #eee); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fdfdfd, #eee); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fdfdfd, #eee); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fdfdfd, #eee); | |
} | |
.ui-btn-up-c a.ui-link-inherit { | |
color: #2F3E46; | |
} | |
.ui-btn-hover-c { | |
border: 1px solid #bbb; | |
background: #dadada; | |
font-weight: bold; | |
color: #101010; | |
text-shadow: 0 1px 1px #fff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#ededed), to(#dadada)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #ededed, #dadada); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #ededed, #dadada); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #ededed, #dadada); /* IE10 */ | |
background-image: -o-linear-gradient(top, #ededed, #dadada); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #ededed, #dadada); | |
} | |
.ui-btn-hover-c a.ui-link-inherit { | |
color: #2F3E46; | |
} | |
.ui-btn-down-c { | |
border: 1px solid #808080; | |
background: #fdfdfd; | |
font-weight: bold; | |
color: #111111; | |
text-shadow: 0 1px 1px #ffffff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#fdfdfd)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #eee, #fdfdfd); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #eee, #fdfdfd); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #eee, #fdfdfd); /* IE10 */ | |
background-image: -o-linear-gradient(top, #eee, #fdfdfd); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #eee, #fdfdfd); | |
} | |
.ui-btn-down-c a.ui-link-inherit { | |
color: #2F3E46; | |
} | |
.ui-btn-up-c, | |
.ui-btn-hover-c, | |
.ui-btn-down-c { | |
font-family: Helvetica, Arial, sans-serif; | |
text-decoration: none; | |
} | |
/* D | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-d { | |
border: 1px solid #ccc; | |
background: #bbb; | |
color: #333; | |
text-shadow: 0 1px 0 #eee; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#ddd), to(#bbb)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #ddd, #bbb); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #ddd, #bbb); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #ddd, #bbb); /* IE10 */ | |
background-image: -o-linear-gradient(top, #ddd, #bbb); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #ddd, #bbb); | |
} | |
.ui-bar-d, | |
.ui-bar-d input, | |
.ui-bar-d select, | |
.ui-bar-d textarea, | |
.ui-bar-d button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-bar-d .ui-link-inherit { | |
color: #333; | |
} | |
.ui-bar-d .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-body-d { | |
border: 1px solid #ccc; | |
color: #333333; | |
text-shadow: 0 1px 0 #fff; | |
background: #ffffff; | |
} | |
.ui-body-d, | |
.ui-body-d input, | |
.ui-body-d select, | |
.ui-body-d textarea, | |
.ui-body-d button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-body-d .ui-link-inherit { | |
color: #333333; | |
} | |
.ui-body-d .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-btn-up-d { | |
border: 1px solid #ccc; | |
background: #fff; | |
font-weight: bold; | |
color: #444; | |
text-shadow: 0 1px 1px #fff; | |
} | |
.ui-btn-up-d a.ui-link-inherit { | |
color: #333; | |
} | |
.ui-btn-hover-d { | |
border: 1px solid #aaa; | |
background: #eeeeee; | |
font-weight: bold; | |
color: #222; | |
cursor: pointer; | |
text-shadow: 0 1px 1px #fff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#eee)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fdfdfd, #eee); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fdfdfd, #eee); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fdfdfd, #eee); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fdfdfd, #eee); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fdfdfd, #eee); | |
} | |
.ui-btn-hover-d a.ui-link-inherit { | |
color: #222; | |
} | |
.ui-btn-down-d { | |
border: 1px solid #aaaaaa; | |
background: #ffffff; | |
font-weight: bold; | |
color: #111; | |
text-shadow: 0 1px 1px #ffffff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#fff)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #eee, #fff); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #eee, #fff); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #eee, #fff); /* IE10 */ | |
background-image: -o-linear-gradient(top, #eee, #fff); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #eee, #fff); | |
} | |
.ui-btn-down-d a.ui-link-inherit { | |
color: #111; | |
} | |
.ui-btn-up-d, | |
.ui-btn-hover-d, | |
.ui-btn-down-d { | |
font-family: Helvetica, Arial, sans-serif; | |
text-decoration: none; | |
} | |
/* E | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-e { | |
border: 1px solid #F7C942; | |
background: #fadb4e; | |
color: #333; | |
text-shadow: 0 1px 0 #fff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fceda7), to(#fadb4e)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fceda7, #fadb4e); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fceda7, #fadb4e); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fceda7, #fadb4e); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fceda7, #fadb4e); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fceda7, #fadb4e); | |
} | |
.ui-bar-e, | |
.ui-bar-e input, | |
.ui-bar-e select, | |
.ui-bar-e textarea, | |
.ui-bar-e button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-bar-e .ui-link-inherit { | |
color: #333; | |
} | |
.ui-bar-e .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-body-e { | |
border: 1px solid #F7C942; | |
color: #333333; | |
text-shadow: 0 1px 0 #fff; | |
background: #faeb9e; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#faeb9e)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fff, #faeb9e); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fff, #faeb9e); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fff, #faeb9e); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fff, #faeb9e); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fff, #faeb9e); | |
} | |
.ui-body-e, | |
.ui-body-e input, | |
.ui-body-e select, | |
.ui-body-e textarea, | |
.ui-body-e button { | |
font-family: Helvetica, Arial, sans-serif; | |
} | |
.ui-body-e .ui-link-inherit { | |
color: #333333; | |
} | |
.ui-body-e .ui-link { | |
color: #2489CE; | |
font-weight: bold; | |
} | |
.ui-btn-up-e { | |
border: 1px solid #F7C942; | |
background: #fadb4e; | |
font-weight: bold; | |
color: #333; | |
text-shadow: 0 1px 0 #fff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fceda7), to(#fadb4e)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fceda7, #fadb4e); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fceda7, #fadb4e); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fceda7, #fadb4e); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fceda7, #fadb4e); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fceda7, #fadb4e); | |
} | |
.ui-btn-up-e a.ui-link-inherit { | |
color: #333; | |
} | |
.ui-btn-hover-e { | |
border: 1px solid #e79952; | |
background: #fbe26f; | |
font-weight: bold; | |
color: #111; | |
text-shadow: 0 1px 1px #fff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf0b5), to(#fbe26f)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fcf0b5, #fbe26f); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fcf0b5, #fbe26f); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fcf0b5, #fbe26f); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fcf0b5, #fbe26f); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fcf0b5, #fbe26f); | |
} | |
.ui-btn-hover-e a.ui-link-inherit { | |
color: #333; | |
} | |
.ui-btn-down-e { | |
border: 1px solid #F7C942; | |
background: #fceda7; | |
font-weight: bold; | |
color: #111; | |
text-shadow: 0 1px 1px #ffffff; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fadb4e), to(#fceda7)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fadb4e, #fceda7); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fadb4e, #fceda7); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fadb4e, #fceda7); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fadb4e, #fceda7); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fadb4e, #fceda7); | |
} | |
.ui-btn-down-e a.ui-link-inherit { | |
color: #333; | |
} | |
.ui-btn-up-e, | |
.ui-btn-hover-e, | |
.ui-btn-down-e { | |
font-family: Helvetica, Arial, sans-serif; | |
text-decoration: none; | |
} | |
/* links within "buttons" | |
-----------------------------------------------------------------------------------------------------------*/ | |
a.ui-link-inherit { | |
text-decoration: none !important; | |
} | |
/* Active class used as the "on" state across all themes | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-btn-active { | |
border: 1px solid #155678; | |
background: #4596ce; | |
font-weight: bold; | |
color: #fff; | |
cursor: pointer; | |
text-shadow: 0 -1px 1px #145072; | |
text-decoration: none; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#85bae4), to(#5393c5)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #85bae4, #5393c5); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #85bae4, #5393c5); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #85bae4, #5393c5); /* IE10 */ | |
background-image: -o-linear-gradient(top, #85bae4, #5393c5); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #85bae4, #5393c5); | |
outline: none; | |
} | |
.ui-btn-active a.ui-link-inherit { | |
color: #fff; | |
} | |
/* button inner top highlight | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-btn-inner { | |
border-top: 1px solid #fff; | |
border-color: rgba(255,255,255,.3); | |
} | |
/* corner rounding classes | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-corner-tl { | |
-moz-border-radius-topleft: .6em; | |
-webkit-border-top-left-radius: .6em; | |
border-top-left-radius: .6em; | |
} | |
.ui-corner-tr { | |
-moz-border-radius-topright: .6em; | |
-webkit-border-top-right-radius: .6em; | |
border-top-right-radius: .6em; | |
} | |
.ui-corner-bl { | |
-moz-border-radius-bottomleft: .6em; | |
-webkit-border-bottom-left-radius: .6em; | |
border-bottom-left-radius: .6em; | |
} | |
.ui-corner-br { | |
-moz-border-radius-bottomright: .6em; | |
-webkit-border-bottom-right-radius: .6em; | |
border-bottom-right-radius: .6em; | |
} | |
.ui-corner-top { | |
-moz-border-radius-topleft: .6em; | |
-webkit-border-top-left-radius: .6em; | |
border-top-left-radius: .6em; | |
-moz-border-radius-topright: .6em; | |
-webkit-border-top-right-radius: .6em; | |
border-top-right-radius: .6em; | |
} | |
.ui-corner-bottom { | |
-moz-border-radius-bottomleft: .6em; | |
-webkit-border-bottom-left-radius: .6em; | |
border-bottom-left-radius: .6em; | |
-moz-border-radius-bottomright: .6em; | |
-webkit-border-bottom-right-radius: .6em; | |
border-bottom-right-radius: .6em; | |
} | |
.ui-corner-right { | |
-moz-border-radius-topright: .6em; | |
-webkit-border-top-right-radius: .6em; | |
border-top-right-radius: .6em; | |
-moz-border-radius-bottomright: .6em; | |
-webkit-border-bottom-right-radius: .6em; | |
border-bottom-right-radius: .6em; | |
} | |
.ui-corner-left { | |
-moz-border-radius-topleft: .6em; | |
-webkit-border-top-left-radius: .6em; | |
border-top-left-radius: .6em; | |
-moz-border-radius-bottomleft: .6em; | |
-webkit-border-bottom-left-radius: .6em; | |
border-bottom-left-radius: .6em; | |
} | |
.ui-corner-all { | |
-moz-border-radius: .6em; | |
-webkit-border-radius: .6em; | |
border-radius: .6em; | |
} | |
/* Interaction cues | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-disabled { | |
opacity: .3; | |
} | |
.ui-disabled, | |
.ui-disabled a { | |
cursor: default; | |
} | |
/* Icons | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-icon { | |
background: #666; | |
background: rgba(0,0,0,.4); | |
background-image: url(images/icons-18-white.png); | |
background-repeat: no-repeat; | |
-moz-border-radius: 9px; | |
-webkit-border-radius: 9px; | |
border-radius: 9px; | |
} | |
/* Alt icon color | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-icon-alt { | |
background: #fff; | |
background: rgba(255,255,255,.3); | |
background-image: url(images/icons-18-black.png); | |
background-repeat: no-repeat; | |
} | |
/* HD/"retina" sprite | |
-----------------------------------------------------------------------------------------------------------*/ | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), | |
only screen and (min--moz-device-pixel-ratio: 1.5), | |
only screen and (min-resolution: 240dpi) { | |
.ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, | |
.ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, | |
.ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, | |
.ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, | |
.ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on { | |
background-image: url(images/icons-36-white.png); | |
-moz-background-size: 776px 18px; | |
-o-background-size: 776px 18px; | |
-webkit-background-size: 776px 18px; | |
background-size: 776px 18px; | |
} | |
.ui-icon-alt { | |
background-image: url(images/icons-36-black.png); | |
} | |
} | |
/* plus minus */ | |
.ui-icon-plus { | |
background-position: -0 50%; | |
} | |
.ui-icon-minus { | |
background-position: -36px 50%; | |
} | |
/* delete/close */ | |
.ui-icon-delete { | |
background-position: -72px 50%; | |
} | |
/* arrows */ | |
.ui-icon-arrow-r { | |
background-position: -108px 50%; | |
} | |
.ui-icon-arrow-l { | |
background-position: -144px 50%; | |
} | |
.ui-icon-arrow-u { | |
background-position: -180px 50%; | |
} | |
.ui-icon-arrow-d { | |
background-position: -216px 50%; | |
} | |
/* misc */ | |
.ui-icon-check { | |
background-position: -252px 50%; | |
} | |
.ui-icon-gear { | |
background-position: -288px 50%; | |
} | |
.ui-icon-refresh { | |
background-position: -324px 50%; | |
} | |
.ui-icon-forward { | |
background-position: -360px 50%; | |
} | |
.ui-icon-back { | |
background-position: -396px 50%; | |
} | |
.ui-icon-grid { | |
background-position: -432px 50%; | |
} | |
.ui-icon-star { | |
background-position: -468px 50%; | |
} | |
.ui-icon-alert { | |
background-position: -504px 50%; | |
} | |
.ui-icon-info { | |
background-position: -540px 50%; | |
} | |
.ui-icon-home { | |
background-position: -576px 50%; | |
} | |
.ui-icon-search { | |
background-position: -612px 50%; | |
} | |
.ui-icon-checkbox-off { | |
background-position: -684px 50%; | |
} | |
.ui-icon-checkbox-on { | |
background-position: -648px 50%; | |
} | |
.ui-icon-radio-off { | |
background-position: -756px 50%; | |
} | |
.ui-icon-radio-on { | |
background-position: -720px 50%; | |
} | |
/* checks,radios */ | |
.ui-checkbox .ui-icon { | |
-moz-border-radius: 3px; | |
-webkit-border-radius: 3px; | |
border-radius: 3px; | |
} | |
.ui-icon-checkbox-off, | |
.ui-icon-radio-off { | |
background-color: transparent; | |
} | |
.ui-checkbox-on .ui-icon, | |
.ui-radio-on .ui-icon { | |
background-color: #4596ce; /* NOTE: this hex should match the active state color. It's repeated here for cascade */ | |
} | |
.ui-icon-searchfield { | |
background-image: url(images/icon-search-black.png); | |
background-size: 16px 16px; | |
} | |
/* loading icon */ | |
.ui-icon-loading { | |
background-image: url(images/ajax-loader.png); | |
width: 40px; | |
height: 40px; | |
-moz-border-radius: 20px; | |
-webkit-border-radius: 20px; | |
border-radius: 20px; | |
background-size: 35px 35px; | |
} | |
/* Button corner classes | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-btn-corner-tl { | |
-moz-border-radius-topleft: 1em; | |
-webkit-border-top-left-radius: 1em; | |
border-top-left-radius: 1em; | |
} | |
.ui-btn-corner-tr { | |
-moz-border-radius-topright: 1em; | |
-webkit-border-top-right-radius: 1em; | |
border-top-right-radius: 1em; | |
} | |
.ui-btn-corner-bl { | |
-moz-border-radius-bottomleft: 1em; | |
-webkit-border-bottom-left-radius: 1em; | |
border-bottom-left-radius: 1em; | |
} | |
.ui-btn-corner-br { | |
-moz-border-radius-bottomright: 1em; | |
-webkit-border-bottom-right-radius: 1em; | |
border-bottom-right-radius: 1em; | |
} | |
.ui-btn-corner-top { | |
-moz-border-radius-topleft: 1em; | |
-webkit-border-top-left-radius: 1em; | |
border-top-left-radius: 1em; | |
-moz-border-radius-topright: 1em; | |
-webkit-border-top-right-radius: 1em; | |
border-top-right-radius: 1em; | |
} | |
.ui-btn-corner-bottom { | |
-moz-border-radius-bottomleft: 1em; | |
-webkit-border-bottom-left-radius: 1em; | |
border-bottom-left-radius: 1em; | |
-moz-border-radius-bottomright: 1em; | |
-webkit-border-bottom-right-radius: 1em; | |
border-bottom-right-radius: 1em; | |
} | |
.ui-btn-corner-right { | |
-moz-border-radius-topright: 1em; | |
-webkit-border-top-right-radius: 1em; | |
border-top-right-radius: 1em; | |
-moz-border-radius-bottomright: 1em; | |
-webkit-border-bottom-right-radius: 1em; | |
border-bottom-right-radius: 1em; | |
} | |
.ui-btn-corner-left { | |
-moz-border-radius-topleft: 1em; | |
-webkit-border-top-left-radius: 1em; | |
border-top-left-radius: 1em; | |
-moz-border-radius-bottomleft: 1em; | |
-webkit-border-bottom-left-radius: 1em; | |
border-bottom-left-radius: 1em; | |
} | |
.ui-btn-corner-all { | |
-moz-border-radius: 1em; | |
-webkit-border-radius: 1em; | |
border-radius: 1em; | |
} | |
/* radius clip workaround for cleaning up corner trapping */ | |
.ui-corner-tl, | |
.ui-corner-tr, | |
.ui-corner-bl, | |
.ui-corner-br, | |
.ui-corner-top, | |
.ui-corner-bottom, | |
.ui-corner-right, | |
.ui-corner-left, | |
.ui-corner-all, | |
.ui-btn-corner-tl, | |
.ui-btn-corner-tr, | |
.ui-btn-corner-bl, | |
.ui-btn-corner-br, | |
.ui-btn-corner-top, | |
.ui-btn-corner-bottom, | |
.ui-btn-corner-right, | |
.ui-btn-corner-left, | |
.ui-btn-corner-all { | |
-webkit-background-clip: padding-box; | |
-moz-background-clip: padding; | |
background-clip: padding-box; | |
} | |
/* Overlay / modal | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-overlay { | |
background: #666; | |
opacity: .5; | |
filter: Alpha(Opacity=50); | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
} | |
.ui-overlay-shadow { | |
-moz-box-shadow: 0px 0px 12px rgba(0,0,0,.6); | |
-webkit-box-shadow: 0px 0px 12px rgba(0,0,0,.6); | |
box-shadow: 0px 0px 12px rgba(0,0,0,.6); | |
} | |
.ui-shadow { | |
-moz-box-shadow: 0px 1px 4px rgba(0,0,0,.3); | |
-webkit-box-shadow: 0px 1px 4px rgba(0,0,0,.3); | |
box-shadow: 0px 1px 4px rgba(0,0,0,.3); | |
} | |
.ui-bar-a .ui-shadow, | |
.ui-bar-b .ui-shadow , | |
.ui-bar-c .ui-shadow { | |
-moz-box-shadow: 0px 1px 0 rgba(255,255,255,.3); | |
-webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.3); | |
box-shadow: 0px 1px 0 rgba(255,255,255,.3); | |
} | |
.ui-shadow-inset { | |
-moz-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); | |
-webkit-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); | |
box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); | |
} | |
.ui-icon-shadow { | |
-moz-box-shadow: 0px 1px 0 rgba(255,255,255,.4); | |
-webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.4); | |
box-shadow: 0px 1px 0 rgba(255,255,255,.4); | |
} | |
/* Focus state - set here for specificity | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-focus { | |
-moz-box-shadow: 0px 0px 12px #387bbe; | |
-webkit-box-shadow: 0px 0px 12px #387bbe; | |
box-shadow: 0px 0px 12px #387bbe; | |
} | |
/* unset box shadow in browsers that don't do it right | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-mobile-nosupport-boxshadow * { | |
-moz-box-shadow: none !important; | |
-webkit-box-shadow: none !important; | |
box-shadow: none !important; | |
} | |
/* ...and bring back focus */ | |
.ui-mobile-nosupport-boxshadow .ui-focus { | |
outline-width: 2px; | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* some unsets - more probably needed */ | |
.ui-mobile, .ui-mobile body { height: 100%; } | |
.ui-mobile fieldset, .ui-page { padding: 0; margin: 0; } | |
.ui-mobile a img, .ui-mobile fieldset { border: 0; } | |
/* responsive page widths */ | |
.ui-mobile-viewport { margin: 0; overflow-x: hidden; -webkit-text-size-adjust: none; -ms-text-size-adjust:none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } | |
/* "page" containers - full-screen views, one should always be in view post-pageload */ | |
.ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page { top: 0; left: 0; width: 100%; min-height: 100%; position: absolute; display: none; border: 0; } | |
.ui-mobile .ui-page-active { display: block; overflow: visible; } | |
/*orientations from js are available */ | |
.portrait, | |
.portrait .ui-page { min-height: 420px; } | |
.landscape, | |
.landscape .ui-page { min-height: 300px; } | |
/* loading screen */ | |
.ui-loading .ui-mobile-viewport { overflow: hidden !important; } | |
.ui-loading .ui-loader { display: block; } | |
.ui-loading .ui-page { overflow: hidden; } | |
.ui-loader { display: none; position: absolute; opacity: .85; z-index: 100; left: 50%; width: 200px; margin-left: -130px; margin-top: -35px; padding: 10px 30px; } | |
.ui-loader h1 { font-size: 15px; text-align: center; } | |
.ui-loader .ui-icon { position: static; display: block; opacity: .9; margin: 0 auto; width: 35px; height: 35px; background-color: transparent; } | |
/*fouc*/ | |
.ui-mobile-rendering > * { visibility: hidden; } | |
/*headers, content panels*/ | |
.ui-bar, .ui-body { position: relative; padding: .4em 15px; overflow: hidden; display: block; clear:both; } | |
.ui-bar { font-size: 16px; margin: 0; } | |
.ui-bar h1, .ui-bar h2, .ui-bar h3, .ui-bar h4, .ui-bar h5, .ui-bar h6 { margin: 0; padding: 0; font-size: 16px; display: inline-block; } | |
.ui-header, .ui-footer { display: block; } | |
.ui-page .ui-header, .ui-page .ui-footer { position: relative; } | |
.ui-header .ui-btn-left { position: absolute; left: 10px; top: .4em; } | |
.ui-header .ui-btn-right { position: absolute; right: 10px; top: .4em; } | |
.ui-header .ui-title, .ui-footer .ui-title { min-height: 1.1em; text-align: center; font-size: 16px; display: block; margin: .6em 90px .8em; padding: 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; outline: 0 !important; } | |
/*content area*/ | |
.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; } | |
.ui-page-fullscreen .ui-content { padding:0; } | |
/* icons sizing */ | |
.ui-icon { width: 18px; height: 18px; } | |
/* fullscreen class on ui-content div */ | |
.ui-fullscreen { } | |
.ui-fullscreen img { max-width: 100%; } | |
/* non-js content hiding */ | |
.ui-nojs { position: absolute; left: -9999px; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.spin { | |
-webkit-transform: rotate(360deg); | |
-webkit-animation-name: spin; | |
-webkit-animation-duration: 1s; | |
-webkit-animation-iteration-count: infinite; | |
-webkit-animation-timing-function: linear; | |
} | |
@-webkit-keyframes spin { | |
from {-webkit-transform: rotate(0deg);} | |
to {-webkit-transform: rotate(360deg);} | |
} | |
/* Transitions from jQtouch (with small modifications): http://www.jqtouch.com/ | |
Built by David Kaneda and maintained by Jonathan Stark. | |
*/ | |
.in, .out { | |
-webkit-animation-timing-function: ease-in-out; | |
-webkit-animation-duration: 350ms; | |
} | |
.slide.in { | |
-webkit-transform: translateX(0); | |
-webkit-animation-name: slideinfromright; | |
} | |
.slide.out { | |
-webkit-transform: translateX(-100%); | |
-webkit-animation-name: slideouttoleft; | |
} | |
.slide.in.reverse { | |
-webkit-transform: translateX(0); | |
-webkit-animation-name: slideinfromleft; | |
} | |
.slide.out.reverse { | |
-webkit-transform: translateX(100%); | |
-webkit-animation-name: slideouttoright; | |
} | |
.slideup.in { | |
-webkit-transform: translateY(0); | |
-webkit-animation-name: slideinfrombottom; | |
z-index: 10; | |
} | |
.slideup.out { | |
-webkit-animation-name: dontmove; | |
z-index: 0; | |
} | |
.slideup.out.reverse { | |
-webkit-transform: translateY(100%); | |
z-index: 10; | |
-webkit-animation-name: slideouttobottom; | |
} | |
.slideup.in.reverse { | |
z-index: 0; | |
-webkit-animation-name: dontmove; | |
} | |
.slidedown.in { | |
-webkit-transform: translateY(0); | |
-webkit-animation-name: slideinfromtop; | |
z-index: 10; | |
} | |
.slidedown.out { | |
-webkit-animation-name: dontmove; | |
z-index: 0; | |
} | |
.slidedown.out.reverse { | |
-webkit-transform: translateY(-100%); | |
z-index: 10; | |
-webkit-animation-name: slideouttotop; | |
} | |
.slidedown.in.reverse { | |
z-index: 0; | |
-webkit-animation-name: dontmove; | |
} | |
@-webkit-keyframes slideinfromright { | |
from { -webkit-transform: translateX(100%); } | |
to { -webkit-transform: translateX(0); } | |
} | |
@-webkit-keyframes slideinfromleft { | |
from { -webkit-transform: translateX(-100%); } | |
to { -webkit-transform: translateX(0); } | |
} | |
@-webkit-keyframes slideouttoleft { | |
from { -webkit-transform: translateX(0); } | |
to { -webkit-transform: translateX(-100%); } | |
} | |
@-webkit-keyframes slideouttoright { | |
from { -webkit-transform: translateX(0); } | |
to { -webkit-transform: translateX(100%); } | |
} | |
@-webkit-keyframes slideinfromtop { | |
from { -webkit-transform: translateY(-100%); } | |
to { -webkit-transform: translateY(0); } | |
} | |
@-webkit-keyframes slideinfrombottom { | |
from { -webkit-transform: translateY(100%); } | |
to { -webkit-transform: translateY(0); } | |
} | |
@-webkit-keyframes slideouttobottom { | |
from { -webkit-transform: translateY(0); } | |
to { -webkit-transform: translateY(100%); } | |
} | |
@-webkit-keyframes slideouttotop { | |
from { -webkit-transform: translateY(0); } | |
to { -webkit-transform: translateY(-100%); } | |
} | |
@-webkit-keyframes fadein { | |
from { opacity: 0; } | |
to { opacity: 1; } | |
} | |
@-webkit-keyframes fadeout { | |
from { opacity: 1; } | |
to { opacity: 0; } | |
} | |
.fade.in { | |
opacity: 1; | |
z-index: 10; | |
-webkit-animation-name: fadein; | |
} | |
.fade.out { | |
z-index: 0; | |
-webkit-animation-name: fadeout; | |
} | |
/* The properties in this rule are only necessary for the 'flip' transition. | |
* We need specify the perspective to create a projection matrix. This will add | |
* some depth as the element flips. The depth number represents the distance of | |
* the viewer from the z-plane. According to the CSS3 spec, 1000 is a moderate | |
* value. | |
*/ | |
.viewport-flip { | |
-webkit-perspective: 1000; | |
position: absolute; | |
} | |
.ui-mobile-viewport-transitioning, | |
.ui-mobile-viewport-transitioning .ui-page { | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
} | |
.flip { | |
-webkit-animation-duration: .65s; | |
-webkit-backface-visibility:hidden; | |
-webkit-transform:translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ | |
} | |
.flip.in { | |
-webkit-transform: rotateY(0) scale(1); | |
-webkit-animation-name: flipinfromleft; | |
} | |
.flip.out { | |
-webkit-transform: rotateY(-180deg) scale(.8); | |
-webkit-animation-name: flipouttoleft; | |
} | |
/* Shake it all about */ | |
.flip.in.reverse { | |
-webkit-transform: rotateY(0) scale(1); | |
-webkit-animation-name: flipinfromright; | |
} | |
.flip.out.reverse { | |
-webkit-transform: rotateY(180deg) scale(.8); | |
-webkit-animation-name: flipouttoright; | |
} | |
@-webkit-keyframes flipinfromright { | |
from { -webkit-transform: rotateY(-180deg) scale(.8); } | |
to { -webkit-transform: rotateY(0) scale(1); } | |
} | |
@-webkit-keyframes flipinfromleft { | |
from { -webkit-transform: rotateY(180deg) scale(.8); } | |
to { -webkit-transform: rotateY(0) scale(1); } | |
} | |
@-webkit-keyframes flipouttoleft { | |
from { -webkit-transform: rotateY(0) scale(1); } | |
to { -webkit-transform: rotateY(-180deg) scale(.8); } | |
} | |
@-webkit-keyframes flipouttoright { | |
from { -webkit-transform: rotateY(0) scale(1); } | |
to { -webkit-transform: rotateY(180deg) scale(.8); } | |
} | |
/* Hackish, but reliable. */ | |
@-webkit-keyframes dontmove { | |
from { opacity: 1; } | |
to { opacity: 1; } | |
} | |
.pop { | |
-webkit-transform-origin: 50% 50%; | |
} | |
.pop.in { | |
-webkit-transform: scale(1); | |
opacity: 1; | |
-webkit-animation-name: popin; | |
z-index: 10; | |
} | |
.pop.out.reverse { | |
-webkit-transform: scale(.2); | |
opacity: 0; | |
-webkit-animation-name: popout; | |
z-index: 10; | |
} | |
.pop.in.reverse { | |
z-index: 0; | |
-webkit-animation-name: dontmove; | |
} | |
@-webkit-keyframes popin { | |
from { | |
-webkit-transform: scale(.2); | |
opacity: 0; | |
} | |
to { | |
-webkit-transform: scale(1); | |
opacity: 1; | |
} | |
} | |
@-webkit-keyframes popout { | |
from { | |
-webkit-transform: scale(1); | |
opacity: 1; | |
} | |
to { | |
-webkit-transform: scale(.2); | |
opacity: 0; | |
} | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* content configurations. */ | |
.ui-grid-a, .ui-grid-b, .ui-grid-c, .ui-grid-d { overflow: hidden; } | |
.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e { margin: 0; padding: 0; border: 0; float: left; min-height:1px;} | |
/* grid solo: 100 - single item fallback */ | |
.ui-grid-solo .ui-block-a { width: 100%; float: none; } | |
/* grid a: 50/50 */ | |
.ui-grid-a .ui-block-a, .ui-grid-a .ui-block-b { width: 50%; } | |
.ui-grid-a .ui-block-a { clear: left; } | |
/* grid b: 33/33/33 */ | |
.ui-grid-b .ui-block-a, .ui-grid-b .ui-block-b, .ui-grid-b .ui-block-c { width: 33.333%; } | |
.ui-grid-b .ui-block-a { clear: left; } | |
/* grid c: 25/25/25/25 */ | |
.ui-grid-c .ui-block-a, .ui-grid-c .ui-block-b, .ui-grid-c .ui-block-c, .ui-grid-c .ui-block-d { width: 25%; } | |
.ui-grid-c .ui-block-a { clear: left; } | |
/* grid d: 20/20/20/20/20 */ | |
.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 20%; } | |
.ui-grid-d .ui-block-a { clear: left; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* fixed page header & footer configuration */ | |
.ui-header, .ui-footer, .ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { position: absolute; overflow: hidden; width: 100%; border-left-width: 0; border-right-width: 0; } | |
.ui-header-fixed, .ui-footer-fixed { | |
z-index: 1000; | |
-webkit-transform: translateZ(0); /* Force header/footer rendering to go through the same rendering pipeline as native page scrolling. */ | |
} | |
.ui-footer-duplicate, .ui-page-fullscreen .ui-fixed-inline { display: none; } | |
.ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { opacity: .9; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-navbar { overflow: hidden; } | |
.ui-navbar ul, .ui-navbar-expanded ul { list-style:none; padding: 0; margin: 0; position: relative; display: block; border: 0;} | |
.ui-navbar-collapsed ul { float: left; width: 75%; margin-right: -2px; } | |
.ui-navbar-collapsed .ui-navbar-toggle { float: left; width: 25%; } | |
.ui-navbar li.ui-navbar-truncate { position: absolute; left: -9999px; top: -9999px; } | |
.ui-navbar li .ui-btn, .ui-navbar .ui-navbar-toggle .ui-btn { display: block; font-size: 12px; text-align: center; margin: 0; border-right-width: 0; } | |
.ui-navbar li .ui-btn { margin-right: -1px; } | |
.ui-navbar li .ui-btn:last-child { margin-right: 0; } | |
.ui-header .ui-navbar li .ui-btn, .ui-header .ui-navbar .ui-navbar-toggle .ui-btn, | |
.ui-footer .ui-navbar li .ui-btn, .ui-footer .ui-navbar .ui-navbar-toggle .ui-btn { border-top-width: 0; border-bottom-width: 0; } | |
.ui-navbar .ui-btn-inner { padding-left: 2px; padding-right: 2px; } | |
.ui-navbar-noicons li .ui-btn .ui-btn-inner, .ui-navbar-noicons .ui-navbar-toggle .ui-btn-inner { padding-top: .8em; padding-bottom: .9em; } | |
/*expanded page styles*/ | |
.ui-navbar-expanded .ui-btn { margin: 0; font-size: 14px; } | |
.ui-navbar-expanded .ui-btn-inner { padding-left: 5px; padding-right: 5px; } | |
.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner { padding: 45px 5px 15px; text-align: center; } | |
.ui-navbar-expanded .ui-btn-icon-top .ui-icon { top: 15px; } | |
.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner { padding: 15px 5px 45px; text-align: center; } | |
.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon { bottom: 15px; } | |
.ui-navbar-expanded li .ui-btn .ui-btn-inner { min-height: 2.5em; } | |
.ui-navbar-expanded .ui-navbar-noicons .ui-btn .ui-btn-inner { padding-top: 1.8em; padding-bottom: 1.9em; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-btn { display: block; text-align: center; cursor:pointer; position: relative; margin: .5em 5px; padding: 0; } | |
.ui-btn:focus, .ui-btn:active { outline: none; } | |
.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; } | |
.ui-btn-inline { display: inline-block; } | |
.ui-btn-inner { padding: .6em 25px; display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; zoom: 1; } | |
.ui-header .ui-btn-inner, .ui-footer .ui-btn-inner, .ui-bar .ui-btn-inner { padding: .4em 8px .5em; } | |
.ui-btn-icon-notext { display: inline-block; width: 20px; height: 20px; padding: 2px 1px 2px 3px; text-indent: -9999px; } | |
.ui-btn-icon-notext .ui-btn-inner { padding: 0; } | |
.ui-btn-icon-notext .ui-btn-text { position: absolute; left: -999px; } | |
.ui-btn-icon-left .ui-btn-inner { padding-left: 33px; } | |
.ui-header .ui-btn-icon-left .ui-btn-inner, | |
.ui-footer .ui-btn-icon-left .ui-btn-inner, | |
.ui-bar .ui-btn-icon-left .ui-btn-inner { padding-left: 27px; } | |
.ui-btn-icon-right .ui-btn-inner { padding-right: 33px; } | |
.ui-header .ui-btn-icon-right .ui-btn-inner, | |
.ui-footer .ui-btn-icon-right .ui-btn-inner, | |
.ui-bar .ui-btn-icon-right .ui-btn-inner { padding-right: 27px; } | |
.ui-btn-icon-top .ui-btn-inner { padding-top: 33px; } | |
.ui-header .ui-btn-icon-top .ui-btn-inner, | |
.ui-footer .ui-btn-icon-top .ui-btn-inner, | |
.ui-bar .ui-btn-icon-top .ui-btn-inner { padding-top: 27px; } | |
.ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 33px; } | |
.ui-header .ui-btn-icon-bottom .ui-btn-inner, | |
.ui-footer .ui-btn-icon-bottom .ui-btn-inner, | |
.ui-bar .ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 27px; } | |
/*btn icon positioning*/ | |
.ui-btn-icon-notext .ui-icon { display: block; } | |
.ui-btn-icon-left .ui-icon, .ui-btn-icon-right .ui-icon { position: absolute; top: 50%; margin-top: -9px; } | |
.ui-btn-icon-top .ui-icon, .ui-btn-icon-bottom .ui-icon { position: absolute; left: 50%; margin-left: -9px; } | |
.ui-btn-icon-left .ui-icon { left: 10px; } | |
.ui-btn-icon-right .ui-icon {right: 10px; } | |
.ui-header .ui-btn-icon-left .ui-icon, | |
.ui-footer .ui-btn-icon-left .ui-icon, | |
.ui-bar .ui-btn-icon-left .ui-icon { left: 4px; } | |
.ui-header .ui-btn-icon-right .ui-icon, | |
.ui-footer .ui-btn-icon-right .ui-icon, | |
.ui-bar .ui-btn-icon-right .ui-icon { right: 4px; } | |
.ui-header .ui-btn-icon-top .ui-icon, | |
.ui-footer .ui-btn-icon-top .ui-icon, | |
.ui-bar .ui-btn-icon-top .ui-icon { top: 4px; } | |
.ui-header .ui-btn-icon-bottom .ui-icon, | |
.ui-footer .ui-btn-icon-bottom .ui-icon, | |
.ui-bar .ui-btn-icon-bottom .ui-icon { bottom: 4px; } | |
.ui-btn-icon-top .ui-icon { top: 5px; } | |
.ui-btn-icon-bottom .ui-icon { bottom: 5px; } | |
/*hiding native button,inputs */ | |
.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: 0; cursor: pointer; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); background: transparent; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-collapsible-contain { margin: .5em 0; } | |
.ui-collapsible-heading { font-size: 16px; display: block; margin: 0 -8px; padding: 0; border-width: 0 0 1px 0; position: relative; } | |
.ui-collapsible-heading a { text-align: left; margin: 0; } | |
.ui-collapsible-heading a .ui-btn-inner { padding-left: 40px; } | |
.ui-collapsible-heading a span.ui-btn { position: absolute; left: 6px; top: 50%; margin: -12px 0 0 0; width: 20px; height: 20px; padding: 1px 0px 1px 2px; text-indent: -9999px; } | |
.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 10px 0; } | |
.ui-collapsible-heading a span.ui-btn .ui-icon { left: 0; margin-top: -10px; } | |
.ui-collapsible-heading-status { position:absolute; left:-9999px; } | |
.ui-collapsible-content { display: block; padding: 10px 0 10px 8px; } | |
.ui-collapsible-content-collapsed { display: none; } | |
.ui-collapsible-set { margin: .5em 0; } | |
.ui-collapsible-set .ui-collapsible-contain { margin: -1px 0 0; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-controlgroup, fieldset.ui-controlgroup { padding: 0; margin: .5em 0 1em; } | |
.ui-bar .ui-controlgroup { margin: 0 .3em; } | |
.ui-controlgroup-label { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; } | |
.ui-controlgroup-controls { display: block; width: 95%;} | |
.ui-controlgroup li { list-style: none; } | |
.ui-controlgroup-vertical .ui-btn, | |
.ui-controlgroup-vertical .ui-checkbox, .ui-controlgroup-vertical .ui-radio { margin: 0; border-bottom-width: 0; } | |
.ui-controlgroup-vertical .ui-controlgroup-last { border-bottom-width: 1px; } | |
.ui-controlgroup-horizontal { padding: 0; } | |
.ui-controlgroup-horizontal .ui-btn, | |
.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { display: inline-block; margin: 0 -5px 0 0; } | |
.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { display: inline; } | |
.ui-controlgroup-horizontal .ui-checkbox .ui-btn, .ui-controlgroup-horizontal .ui-radio .ui-btn, | |
.ui-controlgroup-horizontal .ui-checkbox:last-child, .ui-controlgroup-horizontal .ui-radio:last-child { margin-right: 0; } | |
.ui-controlgroup-horizontal .ui-controlgroup-last { margin-right: 0; } | |
.ui-controlgroup .ui-checkbox label, .ui-controlgroup .ui-radio label { font-size: 16px; } | |
/* conflicts with listview.. | |
.ui-controlgroup .ui-btn-icon-notext { width: 30px; height: 30px; text-indent: -9999px; } | |
.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner { padding: 5px 6px 5px 5px; } | |
*/ | |
@media all and (min-width: 450px){ | |
.ui-controlgroup-label { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } | |
.ui-controlgroup-controls { width: 60%; display: inline-block; } | |
} /* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-dialog { min-height: 480px; } | |
.ui-dialog .ui-header, .ui-dialog .ui-content, .ui-dialog .ui-footer { margin: 15px; position: relative; } | |
.ui-dialog .ui-header, .ui-dialog .ui-footer { z-index: 10; width: auto; } | |
.ui-dialog .ui-content, .ui-dialog .ui-footer { margin-top: -15px; }/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-checkbox, .ui-radio { position:relative; margin: .2em 0 .5em; z-index: 1; } | |
.ui-checkbox .ui-btn, .ui-radio .ui-btn { margin: 0; text-align: left; z-index: 2; } | |
.ui-checkbox .ui-btn-inner, .ui-radio .ui-btn-inner { white-space: normal; } | |
.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner { padding-left: 45px; } | |
.ui-checkbox .ui-btn-icon-right .ui-btn-inner, .ui-radio .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } | |
.ui-checkbox .ui-icon, .ui-radio .ui-icon { top: 1.1em; } | |
.ui-checkbox .ui-btn-icon-left .ui-icon, .ui-radio .ui-btn-icon-left .ui-icon {left: 15px; } | |
.ui-checkbox .ui-btn-icon-right .ui-icon, .ui-radio .ui-btn-icon-right .ui-icon {right: 15px; } | |
/* input, label positioning */ | |
.ui-checkbox input,.ui-radio input { position:absolute; left:20px; top:50%; width: 10px; height: 10px; margin:-5px 0 0 0; outline: 0 !important; z-index: 1; }/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-field-contain { padding: 1.5em 0; margin: 0; border-bottom-width: 1px; overflow: visible; } | |
.ui-field-contain:first-child { border-top-width: 0; } | |
@media all and (min-width: 450px){ | |
.ui-field-contain { border-width: 0; padding: 0; margin: 1em 0; } | |
} /* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-select { display: block; position: relative; } | |
.ui-select select { position: absolute; left: -9999px; top: -9999px; } | |
.ui-select .ui-btn { overflow: hidden; } | |
.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); } | |
@-moz-document url-prefix() {.ui-select .ui-btn select { opacity: 0.0001; }} | |
.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; text-indent: 0; } | |
.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } | |
.ui-select .ui-btn-icon-right .ui-icon { right: 15px; } | |
/* labels */ | |
label.ui-select { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; display: block; } | |
/*listbox*/ | |
.ui-select .ui-btn-text, .ui-selectmenu .ui-btn-text { display: block; min-height: 1em; } | |
.ui-select .ui-btn-text { text-overflow: ellipsis; overflow: hidden;} | |
.ui-selectmenu { position: absolute; padding: 0; z-index: 100 !important; width: 80%; max-width: 350px; padding: 6px; } | |
.ui-selectmenu .ui-listview { margin: 0; } | |
.ui-selectmenu .ui-btn.ui-li-divider { cursor: default; } | |
.ui-selectmenu-hidden { top: -9999px; left: -9999px; } | |
.ui-selectmenu-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 99; } | |
.ui-screen-hidden, .ui-selectmenu-list .ui-li .ui-icon { display: none; } | |
.ui-selectmenu-list .ui-li .ui-icon { display: block; } | |
.ui-li.ui-selectmenu-placeholder { display: none; } | |
.ui-selectmenu .ui-header .ui-title { margin: 0.6em 46px 0.8em; } | |
@media all and (min-width: 450px){ | |
label.ui-select { display: inline-block; width: 20%; margin: 0 2% 0 0; } | |
.ui-select { width: 60%; display: inline-block; } | |
} | |
/* when no placeholder is defined in a multiple select, the header height doesn't even extend past the close button. this shim's content in there */ | |
.ui-selectmenu .ui-header h1:after { content: '.'; visibility: hidden; }/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
label.ui-input-text { font-size: 16px; line-height: 1.4; display: block; font-weight: normal; margin: 0 0 .3em; } | |
input.ui-input-text, textarea.ui-input-text { background-image: none; padding: .4em; line-height: 1.4; font-size: 16px; display: block; width: 95%; } | |
input.ui-input-text { -webkit-appearance: none; } | |
textarea.ui-input-text { height: 50px; -webkit-transition: height 200ms linear; -moz-transition: height 200ms linear; -o-transition: height 200ms linear; transition: height 200ms linear; } | |
.ui-input-search { padding: 0 30px; width: 77%; background-position: 8px 50%; background-repeat: no-repeat; position: relative; } | |
.ui-input-search input.ui-input-text { border: none; width: 98%; padding: .4em 0; margin: 0; display: block; background: transparent none; outline: 0 !important; } | |
.ui-input-search .ui-input-clear { position: absolute; right: 0; top: 50%; margin-top: -14px; } | |
.ui-input-search .ui-input-clear-hidden { display: none; } | |
/* orientation adjustments - incomplete!*/ | |
@media all and (min-width: 450px){ | |
label.ui-input-text { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0 } | |
input.ui-input-text, | |
textarea.ui-input-text, | |
.ui-input-search { width: 60%; display: inline-block; } | |
.ui-input-search { width: 50%; } | |
.ui-input-search input.ui-input-text { width: 98%; /*echos rule from above*/ } | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-listview { margin: 0; counter-reset: listnumbering; } | |
.ui-content .ui-listview { margin: -15px; } | |
.ui-content .ui-listview-inset { margin: 1em 0; } | |
.ui-listview, .ui-li { list-style:none; padding:0; } | |
.ui-li, .ui-li.ui-field-contain { display: block; margin:0; position: relative; overflow: visible; text-align: left; border-width: 0; border-top-width: 1px; } | |
.ui-li .ui-btn-text a.ui-link-inherit { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } | |
.ui-li-divider, .ui-li-static { padding: .5em 15px; font-size: 14px; font-weight: bold; } | |
.ui-li-divider { counter-reset: listnumbering; } | |
ol.ui-listview .ui-link-inherit:before, ol.ui-listview .ui-li-static:before, .ui-li-dec { font-size: .8em; display: inline-block; padding-right: .3em; font-weight: normal;counter-increment: listnumbering; content: counter(listnumbering) ". "; } | |
ol.ui-listview .ui-li-jsnumbering:before { content: "" !important; } /* to avoid chance of duplication */ | |
.ui-listview-inset .ui-li { border-right-width: 1px; border-left-width: 1px; } | |
.ui-li:last-child, .ui-li.ui-field-contain:last-child { border-bottom-width: 1px; } | |
.ui-li>.ui-btn-inner { display: block; position: relative; padding: 0; } | |
.ui-li .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li { padding: .7em 75px .7em 15px; display: block; } | |
.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-thumb { min-height: 60px; padding-left: 100px; } | |
.ui-li-has-icon .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-icon { min-height: 20px; padding-left: 40px; } | |
.ui-li-heading { font-size: 16px; font-weight: bold; display: block; margin: .6em 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } | |
.ui-li-desc { font-size: 12px; font-weight: normal; display: block; margin: -.5em 0 .6em; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } | |
.ui-li-thumb, .ui-li-icon { position: absolute; left: 1px; top: 0; max-height: 80px; max-width: 80px; } | |
.ui-li-icon { max-height: 40px; max-width: 40px; left: 10px; top: .9em; } | |
.ui-li-thumb, .ui-li-icon, .ui-li-content { float: left; margin-right: 10px; } | |
.ui-li-aside { float: right; width: 50%; text-align: right; margin: .3em 0; } | |
@media all and (min-width: 480px){ | |
.ui-li-aside { width: 45%; } | |
} | |
.ui-li-divider { cursor: default; } | |
.ui-li-has-alt .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-alt { padding-right: 95px; } | |
.ui-li-count { position: absolute; font-size: 11px; font-weight: bold; padding: .2em .5em; top: 50%; margin-top: -.9em; right: 38px; } | |
.ui-li-divider .ui-li-count, .ui-li-static .ui-li-count { right: 10px; } | |
.ui-li-has-alt .ui-li-count { right: 55px; } | |
.ui-li-link-alt { position: absolute; width: 40px; height: 100%; border-width: 0; border-left-width: 1px; top: 0; right: 0; margin: 0; padding: 0; } | |
.ui-li-link-alt .ui-btn { overflow: hidden; position: absolute; right: 8px; top: 50%; margin: -11px 0 0 0; border-bottom-width: 1px; } | |
.ui-li-link-alt .ui-btn-inner { padding: 0; position: static; } | |
.ui-li-link-alt .ui-btn .ui-icon { right: 50%; margin-right: -9px; } | |
.ui-listview-filter { border-width: 0; overflow: hidden; margin: -15px -15px 15px -15px } | |
.ui-listview-filter .ui-input-search { margin: 5px; width: auto; display: block; } | |
.ui-listview-filter-inset { margin: -15px -5px -15px -5px; background: transparent; } | |
.ui-li.ui-screen-hidden{display:none;} | |
/* Odd iPad positioning issue. */ | |
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { | |
.ui-li .ui-btn-text { overflow: visible; } | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
label.ui-slider { display: block; } | |
input.ui-slider-input { display: inline-block; width: 50px; } | |
select.ui-slider-switch { display: none; } | |
div.ui-slider { position: relative; display: inline-block; overflow: visible; height: 15px; padding: 0; margin: 0 2% 0 20px; top: 4px; width: 66%; } | |
a.ui-slider-handle { position: absolute; z-index: 10; top: 50%; width: 28px; height: 28px; margin-top: -15px; margin-left: -15px; } | |
a.ui-slider-handle .ui-btn-inner { padding-left: 0; padding-right: 0; } | |
@media all and (min-width: 480px){ | |
label.ui-slider { display: inline-block; width: 20%; margin: 0 2% 0 0; } | |
div.ui-slider { width: 45%; } | |
} | |
div.ui-slider-switch { height: 32px; overflow: hidden; margin-left: 0; } | |
div.ui-slider-inneroffset { margin-left: 50%; position: absolute; top: 1px; height: 100%; width: 50%; } | |
div.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; } | |
div.ui-slider-labelbg { position: absolute; top:0; margin: 0; border-width: 0; } | |
div.ui-slider-switch div.ui-slider-labelbg-a { width: 60%; height: 100%; left: 0; } | |
div.ui-slider-switch div.ui-slider-labelbg-b { width: 60%; height: 100%; right: 0; } | |
.ui-slider-switch-a div.ui-slider-labelbg-a, .ui-slider-switch-b div.ui-slider-labelbg-b { z-index: -1; } | |
.ui-slider-switch-a div.ui-slider-labelbg-b, .ui-slider-switch-b div.ui-slider-labelbg-a { z-index: 0; } | |
div.ui-slider-switch a.ui-slider-handle { z-index: 20; width: 101%; height: 32px; margin-top: -18px; margin-left: -101%; } | |
span.ui-slider-label { width: 100%; position: absolute;height: 32px; font-size: 16px; text-align: center; line-height: 2; background: none; border-color: transparent; } | |
span.ui-slider-label-a { left: -100%; margin-right: -1px } | |
span.ui-slider-label-b { right: -100%; margin-left: -1px } | |
/*! | |
* jQuery Mobile v1.0rc1 | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
/*! | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* Swatches */ | |
/* A | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-a { | |
border: 1px solid #2A2A2A /*{a-bar-border}*/; | |
background: #111111 /*{a-bar-background-color}*/; | |
color: #ffffff /*{a-bar-color}*/; | |
font-weight: bold; | |
text-shadow: 0 /*{a-bar-shadow-x}*/ -1px /*{a-bar-shadow-y}*/ 1px /*{a-bar-shadow-radius}*/ #000000 /*{a-bar-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c /*{a-bar-background-start}*/), to(#111 /*{a-bar-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #3c3c3c /*{a-bar-background-start}*/, #111 /*{a-bar-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #3c3c3c /*{a-bar-background-start}*/, #111 /*{a-bar-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #3c3c3c /*{a-bar-background-start}*/, #111 /*{a-bar-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #3c3c3c /*{a-bar-background-start}*/, #111 /*{a-bar-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #3c3c3c /*{a-bar-background-start}*/, #111 /*{a-bar-background-end}*/); | |
} | |
.ui-bar-a, | |
.ui-bar-a input, | |
.ui-bar-a select, | |
.ui-bar-a textarea, | |
.ui-bar-a button { | |
font-family: Helvetica, Arial, sans-serif /*{a-bar-font}*/; | |
} | |
.ui-bar-a .ui-link-inherit { | |
color: #fff /*{a-bar-color}*/; | |
} | |
.ui-bar-a .ui-link { | |
color: #7cc4e7 /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-body-a { | |
border: 1px solid #2A2A2A /*{a-body-border}*/; | |
background: #222222 /*{a-body-background-color}*/; | |
color: #fff /*{a-body-color}*/; | |
text-shadow: 0 /*{a-body-shadow-x}*/ 1px /*{a-body-shadow-y}*/ 0 /*{a-body-shadow-radius}*/ #000 /*{a-body-shadow-color}*/; | |
font-weight: normal; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#666 /*{a-body-background-start}*/), to(#222 /*{a-body-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #666 /*{a-body-background-start}*/, #222 /*{a-body-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #666 /*{a-body-background-start}*/, #222 /*{a-body-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #666 /*{a-body-background-start}*/, #222 /*{a-body-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #666 /*{a-body-background-start}*/, #222 /*{a-body-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #666 /*{a-body-background-start}*/, #222 /*{a-body-background-end}*/); | |
} | |
.ui-body-a, | |
.ui-body-a input, | |
.ui-body-a select, | |
.ui-body-a textarea, | |
.ui-body-a button { | |
font-family: Helvetica, Arial, sans-serif /*{a-body-font}*/; | |
} | |
.ui-body-a .ui-link-inherit { | |
color: #fff /*{a-body-color}*/; | |
} | |
.ui-body-a .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-br { | |
border-bottom: rgb(130,130,130); | |
border-bottom: rgba(130,130,130,.3); | |
border-bottom-width: 1px; | |
border-bottom-style: solid; | |
} | |
.ui-btn-up-a { | |
border: 1px solid #222 /*{a-bup-border}*/; | |
background: #333333 /*{a-bup-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{a-bup-color}*/; | |
text-shadow: 0 /*{a-bup-shadow-x}*/ -1px /*{a-bup-shadow-y}*/ 1px /*{a-bup-shadow-radius}*/ #000 /*{a-bup-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#555 /*{a-bup-background-start}*/), to(#333 /*{a-bup-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #555 /*{a-bup-background-start}*/, #333 /*{a-bup-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #555 /*{a-bup-background-start}*/, #333 /*{a-bup-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #555 /*{a-bup-background-start}*/, #333 /*{a-bup-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #555 /*{a-bup-background-start}*/, #333 /*{a-bup-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #555 /*{a-bup-background-start}*/, #333 /*{a-bup-background-end}*/); | |
} | |
.ui-btn-up-a a.ui-link-inherit { | |
color: #fff /*{a-bup-color}*/; | |
} | |
.ui-btn-hover-a { | |
border: 1px solid #000 /*{a-bhover-border}*/; | |
background: #444444 /*{a-bhover-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{a-bhover-color}*/; | |
text-shadow: 0 /*{a-bhover-shadow-x}*/ -1px /*{a-bhover-shadow-y}*/ 1px /*{a-bhover-shadow-radius}*/ #000 /*{a-bhover-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#666 /*{a-bhover-background-start}*/), to(#444 /*{a-bhover-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #666 /*{a-bhover-background-start}*/, #444 /*{a-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #666 /*{a-bhover-background-start}*/, #444 /*{a-bhover-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #666 /*{a-bhover-background-start}*/, #444 /*{a-bhover-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #666 /*{a-bhover-background-start}*/, #444 /*{a-bhover-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #666 /*{a-bhover-background-start}*/, #444 /*{a-bhover-background-end}*/); | |
} | |
.ui-btn-hover-a a.ui-link-inherit { | |
color: #fff /*{a-bhover-color}*/; | |
} | |
.ui-btn-down-a { | |
border: 1px solid #000 /*{a-bdown-border}*/; | |
background: #3d3d3d /*{a-bdown-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{a-bdown-color}*/; | |
text-shadow: 0 /*{a-bdown-shadow-x}*/ -1px /*{a-bdown-shadow-y}*/ 1px /*{a-bdown-shadow-radius}*/ #000 /*{a-bdown-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#333 /*{a-bdown-background-start}*/), to(#5a5a5a /*{a-bdown-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #333 /*{a-bdown-background-start}*/, #5a5a5a /*{a-bdown-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #333 /*{a-bdown-background-start}*/, #5a5a5a /*{a-bdown-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #333 /*{a-bdown-background-start}*/, #5a5a5a /*{a-bdown-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #333 /*{a-bdown-background-start}*/, #5a5a5a /*{a-bdown-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #333 /*{a-bdown-background-start}*/, #5a5a5a /*{a-bdown-background-end}*/); | |
} | |
.ui-btn-down-a a.ui-link-inherit { | |
color: #fff /*{a-bdown-color}*/; | |
} | |
.ui-btn-up-a, | |
.ui-btn-hover-a, | |
.ui-btn-down-a { | |
font-family: Helvetica, Arial, sans-serif /*{a-button-font}*/; | |
text-decoration: none; | |
} | |
/* B | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-b { | |
border: 1px solid #456f9a /*{b-bar-border}*/; | |
background: #5e87b0 /*{b-bar-background-color}*/; | |
color: #fff /*{b-bar-color}*/; | |
font-weight: bold; | |
text-shadow: 0 /*{b-bar-shadow-x}*/ -1px /*{b-bar-shadow-y}*/ 1px /*{b-bar-shadow-radius}*/ #254f7a /*{b-bar-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#81a8ce /*{b-bar-background-start}*/), to(#5e87b0 /*{b-bar-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #81a8ce /*{b-bar-background-start}*/, #5e87b0 /*{b-bar-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #81a8ce /*{b-bar-background-start}*/, #5e87b0 /*{b-bar-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #81a8ce /*{b-bar-background-start}*/, #5e87b0 /*{b-bar-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #81a8ce /*{b-bar-background-start}*/, #5e87b0 /*{b-bar-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #81a8ce /*{b-bar-background-start}*/, #5e87b0 /*{b-bar-background-end}*/); | |
} | |
.ui-bar-b, | |
.ui-bar-b input, | |
.ui-bar-b select, | |
.ui-bar-b textarea, | |
.ui-bar-b button { | |
font-family: Helvetica, Arial, sans-serif /*{b-bar-font}*/; | |
} | |
.ui-bar-b .ui-link-inherit { | |
color: #fff /*{b-bar-color}*/; | |
} | |
.ui-bar-b .ui-link { | |
color: #7cc4e7 /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-body-b { | |
border: 1px solid #C6C6C6 /*{b-body-border}*/; | |
background: #cccccc /*{b-body-background-color}*/; | |
color: #333333 /*{b-body-color}*/; | |
text-shadow: 0 /*{b-body-shadow-x}*/ 1px /*{b-body-shadow-y}*/ 0 /*{b-body-shadow-radius}*/ #fff /*{b-body-shadow-color}*/; | |
font-weight: normal; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#e6e6e6 /*{b-body-background-start}*/), to(#ccc /*{b-body-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #e6e6e6 /*{b-body-background-start}*/, #ccc /*{b-body-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #e6e6e6 /*{b-body-background-start}*/, #ccc /*{b-body-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #e6e6e6 /*{b-body-background-start}*/, #ccc /*{b-body-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #e6e6e6 /*{b-body-background-start}*/, #ccc /*{b-body-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #e6e6e6 /*{b-body-background-start}*/, #ccc /*{b-body-background-end}*/); | |
} | |
.ui-body-b, | |
.ui-body-b input, | |
.ui-body-b select, | |
.ui-body-b textarea, | |
.ui-body-b button { | |
font-family: Helvetica, Arial, sans-serif /*{b-body-font}*/; | |
} | |
.ui-body-b .ui-link-inherit { | |
color: #333333 /*{b-body-color}*/; | |
} | |
.ui-body-b .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-btn-up-b { | |
border: 1px solid #145072 /*{b-bup-border}*/; | |
background: #2567ab /*{b-bup-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{b-bup-color}*/; | |
text-shadow: 0 /*{b-bup-shadow-x}*/ -1px /*{b-bup-shadow-y}*/ 1px /*{b-bup-shadow-radius}*/ #145072 /*{b-bup-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#5f9cc5 /*{b-bup-background-start}*/), to(#396b9e /*{b-bup-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #5f9cc5 /*{b-bup-background-start}*/, #396b9e /*{b-bup-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #5f9cc5 /*{b-bup-background-start}*/, #396b9e /*{b-bup-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #5f9cc5 /*{b-bup-background-start}*/, #396b9e /*{b-bup-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #5f9cc5 /*{b-bup-background-start}*/, #396b9e /*{b-bup-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #5f9cc5 /*{b-bup-background-start}*/, #396b9e /*{b-bup-background-end}*/); | |
} | |
.ui-btn-up-b a.ui-link-inherit { | |
color: #fff /*{b-bup-color}*/; | |
} | |
.ui-btn-hover-b { | |
border: 1px solid #00516e /*{b-bhover-border}*/; | |
background: #4b88b6 /*{b-bhover-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{b-bhover-color}*/; | |
text-shadow: 0 /*{b-bhover-shadow-x}*/ -1px /*{b-bhover-shadow-y}*/ 1px /*{b-bhover-shadow-radius}*/ #014D68 /*{b-bhover-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#72b0d4 /*{b-bhover-background-start}*/), to(#4b88b6 /*{b-bhover-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #72b0d4 /*{b-bhover-background-start}*/, #4b88b6 /*{b-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #72b0d4 /*{b-bhover-background-start}*/, #4b88b6 /*{b-bhover-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #72b0d4 /*{b-bhover-background-start}*/, #4b88b6 /*{b-bhover-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #72b0d4 /*{b-bhover-background-start}*/, #4b88b6 /*{b-bhover-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #72b0d4 /*{b-bhover-background-start}*/, #4b88b6 /*{b-bhover-background-end}*/); | |
} | |
.ui-btn-hover-b a.ui-link-inherit { | |
color: #fff /*{b-bhover-color}*/; | |
} | |
.ui-btn-down-b { | |
border: 1px solid #225377 /*{b-bdown-border}*/; | |
background: #4e89c5 /*{b-bdown-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{b-bdown-color}*/; | |
text-shadow: 0 /*{b-bdown-shadow-x}*/ -1px /*{b-bdown-shadow-y}*/ 1px /*{b-bdown-shadow-radius}*/ #225377 /*{b-bdown-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#396b9e /*{b-bdown-background-start}*/), to(#4e89c5 /*{b-bdown-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #396b9e /*{b-bdown-background-start}*/, #4e89c5 /*{b-bdown-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #396b9e /*{b-bdown-background-start}*/, #4e89c5 /*{b-bdown-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #396b9e /*{b-bdown-background-start}*/, #4e89c5 /*{b-bdown-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #396b9e /*{b-bdown-background-start}*/, #4e89c5 /*{b-bdown-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #396b9e /*{b-bdown-background-start}*/, #4e89c5 /*{b-bdown-background-end}*/); | |
} | |
.ui-btn-down-b a.ui-link-inherit { | |
color: #fff /*{b-bdown-color}*/; | |
} | |
.ui-btn-up-b, | |
.ui-btn-hover-b, | |
.ui-btn-down-b { | |
font-family: Helvetica, Arial, sans-serif /*{b-button-font}*/; | |
text-decoration: none; | |
} | |
/* C | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-c { | |
border: 1px solid #B3B3B3 /*{c-bar-border}*/; | |
background: #e9eaeb /*{c-bar-background-color}*/; | |
color: #3E3E3E /*{c-bar-color}*/; | |
font-weight: bold; | |
text-shadow: 0 /*{c-bar-shadow-x}*/ 1px /*{c-bar-shadow-y}*/ 1px /*{c-bar-shadow-radius}*/ #fff /*{c-bar-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0f0f0 /*{c-bar-background-start}*/), to(#e9eaeb /*{c-bar-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #f0f0f0 /*{c-bar-background-start}*/, #e9eaeb /*{c-bar-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #f0f0f0 /*{c-bar-background-start}*/, #e9eaeb /*{c-bar-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #f0f0f0 /*{c-bar-background-start}*/, #e9eaeb /*{c-bar-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #f0f0f0 /*{c-bar-background-start}*/, #e9eaeb /*{c-bar-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #f0f0f0 /*{c-bar-background-start}*/, #e9eaeb /*{c-bar-background-end}*/); | |
} | |
.ui-bar-c .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-bar-c, | |
.ui-bar-c input, | |
.ui-bar-c select, | |
.ui-bar-c textarea, | |
.ui-bar-c button { | |
font-family: Helvetica, Arial, sans-serif /*{c-bar-font}*/; | |
} | |
.ui-body-c { | |
border: 1px solid #B3B3B3 /*{c-body-border}*/; | |
color: #333333 /*{c-body-color}*/; | |
text-shadow: 0 /*{c-body-shadow-x}*/ 1px /*{c-body-shadow-y}*/ 0 /*{c-body-shadow-radius}*/ #fff /*{c-body-shadow-color}*/; | |
background: #f0f0f0 /*{c-body-background-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee /*{c-body-background-start}*/), to(#ddd /*{c-body-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #eee /*{c-body-background-start}*/, #ddd /*{c-body-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #eee /*{c-body-background-start}*/, #ddd /*{c-body-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #eee /*{c-body-background-start}*/, #ddd /*{c-body-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #eee /*{c-body-background-start}*/, #ddd /*{c-body-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #eee /*{c-body-background-start}*/, #ddd /*{c-body-background-end}*/); | |
} | |
.ui-body-c, | |
.ui-body-c input, | |
.ui-body-c select, | |
.ui-body-c textarea, | |
.ui-body-c button { | |
font-family: Helvetica, Arial, sans-serif /*{c-body-font}*/; | |
} | |
.ui-body-c .ui-link-inherit { | |
color: #333333 /*{c-body-color}*/; | |
} | |
.ui-body-c .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-btn-up-c { | |
border: 1px solid #ccc /*{c-bup-border}*/; | |
background: #eee /*{c-bup-background-color}*/; | |
font-weight: bold; | |
color: #444 /*{c-bup-color}*/; | |
text-shadow: 0 /*{c-bup-shadow-x}*/ 1px /*{c-bup-shadow-y}*/ 1px /*{c-bup-shadow-radius}*/ #f6f6f6 /*{c-bup-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd /*{c-bup-background-start}*/), to(#eee /*{c-bup-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fdfdfd /*{c-bup-background-start}*/, #eee /*{c-bup-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fdfdfd /*{c-bup-background-start}*/, #eee /*{c-bup-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fdfdfd /*{c-bup-background-start}*/, #eee /*{c-bup-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fdfdfd /*{c-bup-background-start}*/, #eee /*{c-bup-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fdfdfd /*{c-bup-background-start}*/, #eee /*{c-bup-background-end}*/); | |
} | |
.ui-btn-up-c a.ui-link-inherit { | |
color: #2F3E46 /*{c-bup-color}*/; | |
} | |
.ui-btn-hover-c { | |
border: 1px solid #bbb /*{c-bhover-border}*/; | |
background: #dadada /*{c-bhover-background-color}*/; | |
font-weight: bold; | |
color: #101010 /*{c-bhover-color}*/; | |
text-shadow: 0 /*{c-bhover-shadow-x}*/ 1px /*{c-bhover-shadow-y}*/ 1px /*{c-bhover-shadow-radius}*/ #fff /*{c-bhover-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#ededed /*{c-bhover-background-start}*/), to(#dadada /*{c-bhover-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #ededed /*{c-bhover-background-start}*/, #dadada /*{c-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #ededed /*{c-bhover-background-start}*/, #dadada /*{c-bhover-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #ededed /*{c-bhover-background-start}*/, #dadada /*{c-bhover-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #ededed /*{c-bhover-background-start}*/, #dadada /*{c-bhover-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #ededed /*{c-bhover-background-start}*/, #dadada /*{c-bhover-background-end}*/); | |
} | |
.ui-btn-hover-c a.ui-link-inherit { | |
color: #2F3E46 /*{c-bhover-color}*/; | |
} | |
.ui-btn-down-c { | |
border: 1px solid #808080 /*{c-bdown-border}*/; | |
background: #fdfdfd /*{c-bdown-background-color}*/; | |
font-weight: bold; | |
color: #111111 /*{c-bdown-color}*/; | |
text-shadow: 0 /*{c-bdown-shadow-x}*/ 1px /*{c-bdown-shadow-y}*/ 1px /*{c-bdown-shadow-radius}*/ #ffffff /*{c-bdown-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee /*{c-bdown-background-start}*/), to(#fdfdfd /*{c-bdown-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #eee /*{c-bdown-background-start}*/, #fdfdfd /*{c-bdown-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #eee /*{c-bdown-background-start}*/, #fdfdfd /*{c-bdown-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #eee /*{c-bdown-background-start}*/, #fdfdfd /*{c-bdown-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #eee /*{c-bdown-background-start}*/, #fdfdfd /*{c-bdown-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #eee /*{c-bdown-background-start}*/, #fdfdfd /*{c-bdown-background-end}*/); | |
} | |
.ui-btn-down-c a.ui-link-inherit { | |
color: #2F3E46 /*{c-bdown-color}*/; | |
} | |
.ui-btn-up-c, | |
.ui-btn-hover-c, | |
.ui-btn-down-c { | |
font-family: Helvetica, Arial, sans-serif /*{c-button-font}*/; | |
text-decoration: none; | |
} | |
/* D | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-d { | |
border: 1px solid #ccc /*{d-bar-border}*/; | |
background: #bbb /*{d-bar-background-color}*/; | |
color: #333 /*{d-bar-color}*/; | |
text-shadow: 0 /*{d-bar-shadow-x}*/ 1px /*{d-bar-shadow-y}*/ 0 /*{d-bar-shadow-radius}*/ #eee /*{d-bar-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#ddd /*{d-bar-background-start}*/), to(#bbb /*{d-bar-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #ddd /*{d-bar-background-start}*/, #bbb /*{d-bar-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #ddd /*{d-bar-background-start}*/, #bbb /*{d-bar-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #ddd /*{d-bar-background-start}*/, #bbb /*{d-bar-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #ddd /*{d-bar-background-start}*/, #bbb /*{d-bar-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #ddd /*{d-bar-background-start}*/, #bbb /*{d-bar-background-end}*/); | |
} | |
.ui-bar-d, | |
.ui-bar-d input, | |
.ui-bar-d select, | |
.ui-bar-d textarea, | |
.ui-bar-d button { | |
font-family: Helvetica, Arial, sans-serif /*{d-bar-font}*/; | |
} | |
.ui-bar-d .ui-link-inherit { | |
color: #333 /*{d-bar-color}*/; | |
} | |
.ui-bar-d .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-body-d { | |
border: 1px solid #ccc /*{d-body-border}*/; | |
color: #333333 /*{d-body-color}*/; | |
text-shadow: 0 /*{d-body-shadow-x}*/ 1px /*{d-body-shadow-y}*/ 0 /*{d-body-shadow-radius}*/ #fff /*{d-body-shadow-color}*/; | |
background: #ffffff /*{d-body-background-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#fff /*{d-body-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fff /*{d-body-background-start}*/, #fff /*{d-body-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fff /*{d-body-background-start}*/, #fff /*{d-body-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fff /*{d-body-background-start}*/, #fff /*{d-body-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fff /*{d-body-background-start}*/, #fff /*{d-body-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fff /*{d-body-background-start}*/, #fff /*{d-body-background-end}*/); | |
} | |
.ui-body-d, | |
.ui-body-d input, | |
.ui-body-d select, | |
.ui-body-d textarea, | |
.ui-body-d button { | |
font-family: Helvetica, Arial, sans-serif /*{d-body-font}*/; | |
} | |
.ui-body-d .ui-link-inherit { | |
color: #333333 /*{d-body-color}*/; | |
} | |
.ui-body-d .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-btn-up-d { | |
border: 1px solid #ccc /*{d-bup-border}*/; | |
background: #fff /*{d-bup-background-color}*/; | |
font-weight: bold; | |
color: #444 /*{d-bup-color}*/; | |
text-shadow: 0 /*{d-bup-shadow-x}*/ 1px /*{d-bup-shadow-y}*/ 1px /*{d-bup-shadow-radius}*/ #fff /*{d-bup-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#fff /*{d-bup-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fff /*{d-bup-background-start}*/, #fff /*{d-bup-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fff /*{d-bup-background-start}*/, #fff /*{d-bup-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fff /*{d-bup-background-start}*/, #fff /*{d-bup-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fff /*{d-bup-background-start}*/, #fff /*{d-bup-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fff /*{d-bup-background-start}*/, #fff /*{d-bup-background-end}*/); | |
} | |
.ui-btn-up-d a.ui-link-inherit { | |
color: #333 /*{d-bup-color}*/; | |
} | |
.ui-btn-hover-d { | |
border: 1px solid #aaa /*{d-bhover-border}*/; | |
background: #eeeeee /*{d-bhover-background-color}*/; | |
font-weight: bold; | |
color: #222 /*{d-bhover-color}*/; | |
cursor: pointer; | |
text-shadow: 0 /*{d-bhover-shadow-x}*/ 1px /*{d-bhover-shadow-y}*/ 1px /*{d-bhover-shadow-radius}*/ #fff /*{d-bhover-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd), to(#eee /*{d-bhover-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fdfdfd /*{d-bhover-background-start}*/, #eee /*{d-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fdfdfd /*{d-bhover-background-start}*/, #eee /*{d-bhover-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fdfdfd /*{d-bhover-background-start}*/, #eee /*{d-bhover-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fdfdfd /*{d-bhover-background-start}*/, #eee /*{d-bhover-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fdfdfd /*{d-bhover-background-start}*/, #eee /*{d-bhover-background-end}*/); | |
} | |
.ui-btn-hover-d a.ui-link-inherit { | |
color: #222 /*{d-bhover-color}*/; | |
} | |
.ui-btn-down-d { | |
border: 1px solid #aaaaaa /*{d-bdown-border}*/; | |
background: #ffffff /*{d-bdown-background-color}*/; | |
font-weight: bold; | |
color: #111 /*{d-bdown-color}*/; | |
text-shadow: 0 /*{d-bdown-shadow-x}*/ 1px /*{d-bdown-shadow-y}*/ 1px /*{d-bdown-shadow-radius}*/ #ffffff /*{d-bdown-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#eee /*{d-bdown-background-start}*/), to(#fff /*{d-bdown-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #eee /*{d-bdown-background-start}*/, #fff /*{d-bdown-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #eee /*{d-bdown-background-start}*/, #fff /*{d-bdown-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #eee /*{d-bdown-background-start}*/, #fff /*{d-bdown-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #eee /*{d-bdown-background-start}*/, #fff /*{d-bdown-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #eee /*{d-bdown-background-start}*/, #fff /*{d-bdown-background-end}*/); | |
} | |
.ui-btn-down-d a.ui-link-inherit { | |
color: #111 /*{d-bdown-color}*/; | |
} | |
.ui-btn-up-d, | |
.ui-btn-hover-d, | |
.ui-btn-down-d { | |
font-family: Helvetica, Arial, sans-serif /*{d-button-font}*/; | |
text-decoration: none; | |
} | |
/* E | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-bar-e { | |
border: 1px solid #F7C942 /*{e-bar-border}*/; | |
background: #fadb4e /*{e-bar-background-color}*/; | |
color: #333 /*{e-bar-color}*/; | |
text-shadow: 0 /*{e-bar-shadow-x}*/ 1px /*{e-bar-shadow-y}*/ 0 /*{e-bar-shadow-radius}*/ #fff /*{e-bar-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fceda7 /*{e-bar-background-start}*/), to(#fadb4e /*{e-bar-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fceda7 /*{e-bar-background-start}*/, #fadb4e /*{e-bar-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fceda7 /*{e-bar-background-start}*/, #fadb4e /*{e-bar-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fceda7 /*{e-bar-background-start}*/, #fadb4e /*{e-bar-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fceda7 /*{e-bar-background-start}*/, #fadb4e /*{e-bar-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fceda7 /*{e-bar-background-start}*/, #fadb4e /*{e-bar-background-end}*/); | |
} | |
.ui-bar-e, | |
.ui-bar-e input, | |
.ui-bar-e select, | |
.ui-bar-e textarea, | |
.ui-bar-e button { | |
font-family: Helvetica, Arial, sans-serif /*{e-bar-font}*/; | |
} | |
.ui-bar-e .ui-link-inherit { | |
color: #333 /*{e-bar-color}*/; | |
} | |
.ui-bar-e .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-body-e { | |
border: 1px solid #F7C942 /*{e-body-border}*/; | |
color: #333333 /*{e-body-color}*/; | |
text-shadow: 0 /*{e-body-shadow-x}*/ 1px /*{e-body-shadow-y}*/ 0 /*{e-body-shadow-radius}*/ #fff /*{e-body-shadow-color}*/; | |
background: #faeb9e /*{e-body-background-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff /*{e-body-background-start}*/), to(#faeb9e /*{e-body-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fff /*{e-body-background-start}*/, #faeb9e /*{e-body-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fff /*{e-body-background-start}*/, #faeb9e /*{e-body-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fff /*{e-body-background-start}*/, #faeb9e /*{e-body-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fff /*{e-body-background-start}*/, #faeb9e /*{e-body-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fff /*{e-body-background-start}*/, #faeb9e /*{e-body-background-end}*/); | |
} | |
.ui-body-e, | |
.ui-body-e input, | |
.ui-body-e select, | |
.ui-body-e textarea, | |
.ui-body-e button { | |
font-family: Helvetica, Arial, sans-serif /*{e-body-font}*/; | |
} | |
.ui-body-e .ui-link-inherit { | |
color: #333333 /*{e-body-color}*/; | |
} | |
.ui-body-e .ui-link { | |
color: #2489CE /*{global-link-color}*/; | |
font-weight: bold; | |
} | |
.ui-btn-up-e { | |
border: 1px solid #F7C942 /*{e-bup-border}*/; | |
background: #fadb4e /*{e-bup-background-color}*/; | |
font-weight: bold; | |
color: #333 /*{e-bup-color}*/; | |
text-shadow: 0 /*{e-bup-shadow-x}*/ 1px /*{e-bup-shadow-y}*/ 0 /*{e-bup-shadow-radius}*/ #fff /*{e-bup-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fceda7 /*{e-bup-background-start}*/), to(#fadb4e /*{e-bup-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fceda7 /*{e-bup-background-start}*/, #fadb4e /*{e-bup-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fceda7 /*{e-bup-background-start}*/, #fadb4e /*{e-bup-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fceda7 /*{e-bup-background-start}*/, #fadb4e /*{e-bup-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fceda7 /*{e-bup-background-start}*/, #fadb4e /*{e-bup-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fceda7 /*{e-bup-background-start}*/, #fadb4e /*{e-bup-background-end}*/); | |
} | |
.ui-btn-up-e a.ui-link-inherit { | |
color: #333 /*{e-bup-color}*/; | |
} | |
.ui-btn-hover-e { | |
border: 1px solid #e79952 /*{e-bhover-border}*/; | |
background: #fbe26f /*{e-bhover-background-color}*/; | |
font-weight: bold; | |
color: #111 /*{e-bhover-color}*/; | |
text-shadow: 0 /*{e-bhover-shadow-x}*/ 1px /*{e-bhover-shadow-y}*/ 1px /*{e-bhover-shadow-radius}*/ #fff /*{e-bhover-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf0b5 /*{e-bhover-background-start}*/), to(#fbe26f /*{e-bhover-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fcf0b5 /*{e-bhover-background-start}*/, #fbe26f /*{e-bhover-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fcf0b5 /*{e-bhover-background-start}*/, #fbe26f /*{e-bhover-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fcf0b5 /*{e-bhover-background-start}*/, #fbe26f /*{e-bhover-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fcf0b5 /*{e-bhover-background-start}*/, #fbe26f /*{e-bhover-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fcf0b5 /*{e-bhover-background-start}*/, #fbe26f /*{e-bhover-background-end}*/); | |
} | |
.ui-btn-hover-e a.ui-link-inherit { | |
color: #333 /*{e-bhover-color}*/; | |
} | |
.ui-btn-down-e { | |
border: 1px solid #F7C942 /*{e-bdown-border}*/; | |
background: #fceda7 /*{e-bdown-background-color}*/; | |
font-weight: bold; | |
color: #111 /*{e-bdown-color}*/; | |
text-shadow: 0 /*{e-bdown-shadow-x}*/ 1px /*{e-bdown-shadow-y}*/ 1px /*{e-bdown-shadow-radius}*/ #ffffff /*{e-bdown-shadow-color}*/; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#fadb4e /*{e-bdown-background-start}*/), to(#fceda7 /*{e-bdown-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #fadb4e /*{e-bdown-background-start}*/, #fceda7 /*{e-bdown-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #fadb4e /*{e-bdown-background-start}*/, #fceda7 /*{e-bdown-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #fadb4e /*{e-bdown-background-start}*/, #fceda7 /*{e-bdown-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #fadb4e /*{e-bdown-background-start}*/, #fceda7 /*{e-bdown-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #fadb4e /*{e-bdown-background-start}*/, #fceda7 /*{e-bdown-background-end}*/); | |
} | |
.ui-btn-down-e a.ui-link-inherit { | |
color: #333 /*{e-bdown-color}*/; | |
} | |
.ui-btn-up-e, | |
.ui-btn-hover-e, | |
.ui-btn-down-e { | |
font-family: Helvetica, Arial, sans-serif /*{e-button-font}*/; | |
text-decoration: none; | |
} | |
/* Structure */ | |
/* links within "buttons" | |
-----------------------------------------------------------------------------------------------------------*/ | |
a.ui-link-inherit { | |
text-decoration: none !important; | |
} | |
/* links and their different states | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-link{ | |
color: #2489CE /*{global-link-color}*/ | |
} | |
.ui-link:hover{ | |
color: #2489CE /*{global-link-hover}*/ | |
} | |
.ui-link:active{ | |
color: #2489CE /*{global-link-active}*/ | |
} | |
.ui-link:visited{ | |
color: #2489CE /*{global-link-visited}*/ | |
} | |
/* Active class used as the "on" state across all themes | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-btn-active { | |
border: 1px solid #155678 /*{global-active-border}*/; | |
background: #4596ce /*{global-active-background-color}*/; | |
font-weight: bold; | |
color: #fff /*{global-active-color}*/; | |
cursor: pointer; | |
text-shadow: 0 /*{global-active-shadow-x}*/ -1px /*{global-active-shadow-y}*/ 1px /*{global-active-shadow-radius}*/ #145072 /*{global-active-shadow-color}*/; | |
text-decoration: none; | |
background-image: -webkit-gradient(linear, left top, left bottom, from(#85bae4 /*{global-active-background-start}*/), to(#5393c5 /*{global-active-background-end}*/)); /* Saf4+, Chrome */ | |
background-image: -webkit-linear-gradient(top, #85bae4 /*{global-active-background-start}*/, #5393c5 /*{global-active-background-end}*/); /* Chrome 10+, Saf5.1+ */ | |
background-image: -moz-linear-gradient(top, #85bae4 /*{global-active-background-start}*/, #5393c5 /*{global-active-background-end}*/); /* FF3.6 */ | |
background-image: -ms-linear-gradient(top, #85bae4 /*{global-active-background-start}*/, #5393c5 /*{global-active-background-end}*/); /* IE10 */ | |
background-image: -o-linear-gradient(top, #85bae4 /*{global-active-background-start}*/, #5393c5 /*{global-active-background-end}*/); /* Opera 11.10+ */ | |
background-image: linear-gradient(top, #85bae4 /*{global-active-background-start}*/, #5393c5 /*{global-active-background-end}*/); | |
outline: none; | |
font-family: Helvetica, Arial, sans-serif /*{global-active-font}*/; | |
} | |
.ui-btn-active a.ui-link-inherit { | |
color: #fff /*{global-active-color}*/; | |
} | |
/* button inner top highlight | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-btn-inner { | |
border-top: 1px solid #fff; | |
border-color: rgba(255,255,255,.3); | |
} | |
/* corner rounding classes | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-corner-tl { | |
-moz-border-radius-topleft: .6em /*{global-radii-blocks}*/; | |
-webkit-border-top-left-radius: .6em /*{global-radii-blocks}*/; | |
border-top-left-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-tr { | |
-moz-border-radius-topright: .6em /*{global-radii-blocks}*/; | |
-webkit-border-top-right-radius: .6em /*{global-radii-blocks}*/; | |
border-top-right-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-bl { | |
-moz-border-radius-bottomleft: .6em /*{global-radii-blocks}*/; | |
-webkit-border-bottom-left-radius: .6em /*{global-radii-blocks}*/; | |
border-bottom-left-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-br { | |
-moz-border-radius-bottomright: .6em /*{global-radii-blocks}*/; | |
-webkit-border-bottom-right-radius: .6em /*{global-radii-blocks}*/; | |
border-bottom-right-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-top { | |
-moz-border-radius-topleft: .6em /*{global-radii-blocks}*/; | |
-webkit-border-top-left-radius: .6em /*{global-radii-blocks}*/; | |
border-top-left-radius: .6em /*{global-radii-blocks}*/; | |
-moz-border-radius-topright: .6em /*{global-radii-blocks}*/; | |
-webkit-border-top-right-radius: .6em /*{global-radii-blocks}*/; | |
border-top-right-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-bottom { | |
-moz-border-radius-bottomleft: .6em /*{global-radii-blocks}*/; | |
-webkit-border-bottom-left-radius: .6em /*{global-radii-blocks}*/; | |
border-bottom-left-radius: .6em /*{global-radii-blocks}*/; | |
-moz-border-radius-bottomright: .6em /*{global-radii-blocks}*/; | |
-webkit-border-bottom-right-radius: .6em /*{global-radii-blocks}*/; | |
border-bottom-right-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-right { | |
-moz-border-radius-topright: .6em /*{global-radii-blocks}*/; | |
-webkit-border-top-right-radius: .6em /*{global-radii-blocks}*/; | |
border-top-right-radius: .6em /*{global-radii-blocks}*/; | |
-moz-border-radius-bottomright: .6em /*{global-radii-blocks}*/; | |
-webkit-border-bottom-right-radius: .6em /*{global-radii-blocks}*/; | |
border-bottom-right-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-left { | |
-moz-border-radius-topleft: .6em /*{global-radii-blocks}*/; | |
-webkit-border-top-left-radius: .6em /*{global-radii-blocks}*/; | |
border-top-left-radius: .6em /*{global-radii-blocks}*/; | |
-moz-border-radius-bottomleft: .6em /*{global-radii-blocks}*/; | |
-webkit-border-bottom-left-radius: .6em /*{global-radii-blocks}*/; | |
border-bottom-left-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-all { | |
-moz-border-radius: .6em /*{global-radii-blocks}*/; | |
-webkit-border-radius: .6em /*{global-radii-blocks}*/; | |
border-radius: .6em /*{global-radii-blocks}*/; | |
} | |
.ui-corner-none { | |
-moz-border-radius: 0; | |
-webkit-border-radius: 0; | |
border-radius: 0; | |
} | |
/* Interaction cues | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-disabled { | |
opacity: .3; | |
} | |
.ui-disabled, | |
.ui-disabled a { | |
cursor: default; | |
} | |
/* Icons | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-icon, | |
.ui-icon-searchfield:after { | |
background: #666 /*{global-icon-color}*/; | |
background: rgba(0,0,0,.4) /*{global-icon-disc}*/; | |
background-image: url(images/icons-18-white.png) /*{global-icon-set}*/; | |
background-repeat: no-repeat; | |
-moz-border-radius: 9px; | |
-webkit-border-radius: 9px; | |
border-radius: 9px; | |
} | |
/* Alt icon color | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-icon-alt { | |
background: #fff; | |
background: rgba(255,255,255,.3); | |
background-image: url(images/icons-18-black.png); | |
background-repeat: no-repeat; | |
} | |
/* HD/"retina" sprite | |
-----------------------------------------------------------------------------------------------------------*/ | |
@media only screen and (-webkit-min-device-pixel-ratio: 1.5), | |
only screen and (min--moz-device-pixel-ratio: 1.5), | |
only screen and (min-resolution: 240dpi) { | |
.ui-icon-plus, .ui-icon-minus, .ui-icon-delete, .ui-icon-arrow-r, | |
.ui-icon-arrow-l, .ui-icon-arrow-u, .ui-icon-arrow-d, .ui-icon-check, | |
.ui-icon-gear, .ui-icon-refresh, .ui-icon-forward, .ui-icon-back, | |
.ui-icon-grid, .ui-icon-star, .ui-icon-alert, .ui-icon-info, .ui-icon-home, .ui-icon-search, .ui-icon-searchfield:after, | |
.ui-icon-checkbox-off, .ui-icon-checkbox-on, .ui-icon-radio-off, .ui-icon-radio-on { | |
background-image: url(images/icons-36-white.png); | |
-moz-background-size: 776px 18px; | |
-o-background-size: 776px 18px; | |
-webkit-background-size: 776px 18px; | |
background-size: 776px 18px; | |
} | |
.ui-icon-alt { | |
background-image: url(images/icons-36-black.png); | |
} | |
} | |
/* plus minus */ | |
.ui-icon-plus { | |
background-position: -0 50%; | |
} | |
.ui-icon-minus { | |
background-position: -36px 50%; | |
} | |
/* delete/close */ | |
.ui-icon-delete { | |
background-position: -72px 50%; | |
} | |
/* arrows */ | |
.ui-icon-arrow-r { | |
background-position: -108px 50%; | |
} | |
.ui-icon-arrow-l { | |
background-position: -144px 50%; | |
} | |
.ui-icon-arrow-u { | |
background-position: -180px 50%; | |
} | |
.ui-icon-arrow-d { | |
background-position: -216px 50%; | |
} | |
/* misc */ | |
.ui-icon-check { | |
background-position: -252px 50%; | |
} | |
.ui-icon-gear { | |
background-position: -288px 50%; | |
} | |
.ui-icon-refresh { | |
background-position: -324px 50%; | |
} | |
.ui-icon-forward { | |
background-position: -360px 50%; | |
} | |
.ui-icon-back { | |
background-position: -396px 50%; | |
} | |
.ui-icon-grid { | |
background-position: -432px 50%; | |
} | |
.ui-icon-star { | |
background-position: -468px 50%; | |
} | |
.ui-icon-alert { | |
background-position: -504px 50%; | |
} | |
.ui-icon-info { | |
background-position: -540px 50%; | |
} | |
.ui-icon-home { | |
background-position: -576px 50%; | |
} | |
.ui-icon-search, | |
.ui-icon-searchfield:after { | |
background-position: -612px 50%; | |
} | |
.ui-icon-checkbox-off { | |
background-position: -684px 50%; | |
} | |
.ui-icon-checkbox-on { | |
background-position: -648px 50%; | |
} | |
.ui-icon-radio-off { | |
background-position: -756px 50%; | |
} | |
.ui-icon-radio-on { | |
background-position: -720px 50%; | |
} | |
/* checks,radios */ | |
.ui-checkbox .ui-icon { | |
-moz-border-radius: 3px; | |
-webkit-border-radius: 3px; | |
border-radius: 3px; | |
} | |
.ui-icon-checkbox-off, | |
.ui-icon-radio-off { | |
background-color: transparent; | |
} | |
.ui-checkbox-on .ui-icon, | |
.ui-radio-on .ui-icon { | |
background-color: #4596ce /*{global-active-background-color}*/; /* NOTE: this hex should match the active state color. It's repeated here for cascade */ | |
} | |
/* loading icon */ | |
.ui-icon-loading { | |
background-image: url(images/ajax-loader.png); | |
width: 40px; | |
height: 40px; | |
-moz-border-radius: 20px; | |
-webkit-border-radius: 20px; | |
border-radius: 20px; | |
background-size: 35px 35px; | |
} | |
/* Button corner classes | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-btn-corner-tl { | |
-moz-border-radius-topleft: 1em /*{global-radii-buttons}*/; | |
-webkit-border-top-left-radius: 1em /*{global-radii-buttons}*/; | |
border-top-left-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-tr { | |
-moz-border-radius-topright: 1em /*{global-radii-buttons}*/; | |
-webkit-border-top-right-radius: 1em /*{global-radii-buttons}*/; | |
border-top-right-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-bl { | |
-moz-border-radius-bottomleft: 1em /*{global-radii-buttons}*/; | |
-webkit-border-bottom-left-radius: 1em /*{global-radii-buttons}*/; | |
border-bottom-left-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-br { | |
-moz-border-radius-bottomright: 1em /*{global-radii-buttons}*/; | |
-webkit-border-bottom-right-radius: 1em /*{global-radii-buttons}*/; | |
border-bottom-right-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-top { | |
-moz-border-radius-topleft: 1em /*{global-radii-buttons}*/; | |
-webkit-border-top-left-radius: 1em /*{global-radii-buttons}*/; | |
border-top-left-radius: 1em /*{global-radii-buttons}*/; | |
-moz-border-radius-topright: 1em /*{global-radii-buttons}*/; | |
-webkit-border-top-right-radius: 1em /*{global-radii-buttons}*/; | |
border-top-right-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-bottom { | |
-moz-border-radius-bottomleft: 1em /*{global-radii-buttons}*/; | |
-webkit-border-bottom-left-radius: 1em /*{global-radii-buttons}*/; | |
border-bottom-left-radius: 1em /*{global-radii-buttons}*/; | |
-moz-border-radius-bottomright: 1em /*{global-radii-buttons}*/; | |
-webkit-border-bottom-right-radius: 1em /*{global-radii-buttons}*/; | |
border-bottom-right-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-right { | |
-moz-border-radius-topright: 1em /*{global-radii-buttons}*/; | |
-webkit-border-top-right-radius: 1em /*{global-radii-buttons}*/; | |
border-top-right-radius: 1em /*{global-radii-buttons}*/; | |
-moz-border-radius-bottomright: 1em /*{global-radii-buttons}*/; | |
-webkit-border-bottom-right-radius: 1em /*{global-radii-buttons}*/; | |
border-bottom-right-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-left { | |
-moz-border-radius-topleft: 1em /*{global-radii-buttons}*/; | |
-webkit-border-top-left-radius: 1em /*{global-radii-buttons}*/; | |
border-top-left-radius: 1em /*{global-radii-buttons}*/; | |
-moz-border-radius-bottomleft: 1em /*{global-radii-buttons}*/; | |
-webkit-border-bottom-left-radius: 1em /*{global-radii-buttons}*/; | |
border-bottom-left-radius: 1em /*{global-radii-buttons}*/; | |
} | |
.ui-btn-corner-all { | |
-moz-border-radius: 1em /*{global-radii-buttons}*/; | |
-webkit-border-radius: 1em /*{global-radii-buttons}*/; | |
border-radius: 1em /*{global-radii-buttons}*/; | |
} | |
/* radius clip workaround for cleaning up corner trapping */ | |
.ui-corner-tl, | |
.ui-corner-tr, | |
.ui-corner-bl, | |
.ui-corner-br, | |
.ui-corner-top, | |
.ui-corner-bottom, | |
.ui-corner-right, | |
.ui-corner-left, | |
.ui-corner-all, | |
.ui-btn-corner-tl, | |
.ui-btn-corner-tr, | |
.ui-btn-corner-bl, | |
.ui-btn-corner-br, | |
.ui-btn-corner-top, | |
.ui-btn-corner-bottom, | |
.ui-btn-corner-right, | |
.ui-btn-corner-left, | |
.ui-btn-corner-all { | |
-webkit-background-clip: padding-box; | |
-moz-background-clip: padding; | |
background-clip: padding-box; | |
} | |
/* Overlay / modal | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-overlay { | |
background: #666; | |
opacity: .5; | |
filter: Alpha(Opacity=50); | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
} | |
.ui-overlay-shadow { | |
-moz-box-shadow: 0px 0px 12px rgba(0,0,0,.6); | |
-webkit-box-shadow: 0px 0px 12px rgba(0,0,0,.6); | |
box-shadow: 0px 0px 12px rgba(0,0,0,.6); | |
} | |
.ui-shadow { | |
-moz-box-shadow: 0px 1px 4px /*{global-box-shadow-size}*/ rgba(0,0,0,.3) /*{global-box-shadow-color}*/; | |
-webkit-box-shadow: 0px 1px 4px /*{global-box-shadow-size}*/ rgba(0,0,0,.3) /*{global-box-shadow-color}*/; | |
box-shadow: 0px 1px 4px /*{global-box-shadow-size}*/ rgba(0,0,0,.3) /*{global-box-shadow-color}*/; | |
} | |
.ui-bar-a .ui-shadow, | |
.ui-bar-b .ui-shadow , | |
.ui-bar-c .ui-shadow { | |
-moz-box-shadow: 0px 1px 0 rgba(255,255,255,.3); | |
-webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.3); | |
box-shadow: 0px 1px 0 rgba(255,255,255,.3); | |
} | |
.ui-shadow-inset { | |
-moz-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); | |
-webkit-box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); | |
box-shadow: inset 0px 1px 4px rgba(0,0,0,.2); | |
} | |
.ui-icon-shadow { | |
-moz-box-shadow: 0px 1px 0 rgba(255,255,255,.4); | |
-webkit-box-shadow: 0px 1px 0 rgba(255,255,255,.4); | |
box-shadow: 0px 1px 0 rgba(255,255,255,.4); | |
} | |
/* Focus state - set here for specificity | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-focus { | |
-moz-box-shadow: 0px 0px 12px #387bbe /*{global-active-background-color}*/; | |
-webkit-box-shadow: 0px 0px 12px #387bbe /*{global-active-background-color}*/; | |
box-shadow: 0px 0px 12px #387bbe /*{global-active-background-color}*/; | |
} | |
/* unset box shadow in browsers that don't do it right | |
-----------------------------------------------------------------------------------------------------------*/ | |
.ui-mobile-nosupport-boxshadow * { | |
-moz-box-shadow: none !important; | |
-webkit-box-shadow: none !important; | |
box-shadow: none !important; | |
} | |
/* ...and bring back focus */ | |
.ui-mobile-nosupport-boxshadow .ui-focus { | |
outline-width: 2px; | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* some unsets - more probably needed */ | |
.ui-mobile, .ui-mobile body { height: 100%; } | |
.ui-mobile fieldset, .ui-page { padding: 0; margin: 0; } | |
.ui-mobile a img, .ui-mobile fieldset { border: 0; } | |
/* responsive page widths */ | |
.ui-mobile-viewport { margin: 0; overflow-x: hidden; -webkit-text-size-adjust: none; -ms-text-size-adjust:none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } | |
/* "page" containers - full-screen views, one should always be in view post-pageload */ | |
.ui-mobile [data-role=page], .ui-mobile [data-role=dialog], .ui-page { top: 0; left: 0; width: 100%; min-height: 100%; position: absolute; display: none; border: 0; } | |
.ui-mobile .ui-page-active { display: block; overflow: visible; } | |
/* on ios4, setting focus on the page element causes flashing during transitions when there is an outline, so we turn off outlines */ | |
.ui-page { outline: none; } | |
/* native overflow scrolling */ | |
.ui-page.ui-mobile-touch-overflow, | |
.ui-mobile-touch-overflow.ui-native-fixed .ui-content { | |
overflow: auto; | |
height: 100%; | |
-webkit-overflow-scrolling: touch; | |
-moz-overflow-scrolling: touch; | |
-o-overflow-scrolling: touch; | |
-ms-overflow-scrolling: touch; | |
overflow-scrolling: touch; | |
} | |
.ui-page.ui-mobile-touch-overflow, | |
.ui-page.ui-mobile-touch-overflow * { | |
/* some level of transform keeps elements from blinking out of visibility on iOS */ | |
-webkit-transform: rotateY(0); | |
} | |
.ui-page.ui-mobile-pre-transition { | |
display: block; | |
} | |
/* loading screen */ | |
.ui-loading .ui-mobile-viewport { overflow: hidden !important; } | |
.ui-loading .ui-loader { display: block; } | |
.ui-loading .ui-page { overflow: hidden; } | |
.ui-loader { display: none; position: absolute; opacity: .85; z-index: 100; left: 50%; width: 200px; margin-left: -130px; margin-top: -35px; padding: 10px 30px; } | |
.ui-loader h1 { font-size: 15px; text-align: center; } | |
.ui-loader .ui-icon { position: static; display: block; opacity: .9; margin: 0 auto; width: 35px; height: 35px; background-color: transparent; } | |
/*fouc*/ | |
.ui-mobile-rendering > * { visibility: hidden; } | |
/*headers, content panels*/ | |
.ui-bar, .ui-body { position: relative; padding: .4em 15px; overflow: hidden; display: block; clear:both; } | |
.ui-bar { font-size: 16px; margin: 0; } | |
.ui-bar h1, .ui-bar h2, .ui-bar h3, .ui-bar h4, .ui-bar h5, .ui-bar h6 { margin: 0; padding: 0; font-size: 16px; display: inline-block; } | |
.ui-header, .ui-footer { display: block; } | |
.ui-page .ui-header, .ui-page .ui-footer { position: relative; } | |
.ui-header .ui-btn-left { position: absolute; left: 10px; top: .4em; } | |
.ui-header .ui-btn-right { position: absolute; right: 10px; top: .4em; } | |
.ui-header .ui-title, .ui-footer .ui-title { min-height: 1.1em; text-align: center; font-size: 16px; display: block; margin: .6em 90px .8em; padding: 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; outline: 0 !important; } | |
/*content area*/ | |
.ui-content { border-width: 0; overflow: visible; overflow-x: hidden; padding: 15px; } | |
.ui-page-fullscreen .ui-content { padding:0; } | |
/* native fixed headers and footers */ | |
.ui-mobile-touch-overflow.ui-page.ui-native-fixed, | |
.ui-mobile-touch-overflow.ui-page.ui-native-fullscreen { | |
overflow: visible; | |
} | |
.ui-mobile-touch-overflow.ui-native-fixed .ui-header, | |
.ui-mobile-touch-overflow.ui-native-fixed .ui-footer { | |
position: fixed; | |
left: 0; | |
right: 0; | |
top: 0; | |
z-index: 200; | |
} | |
.ui-mobile-touch-overflow.ui-page.ui-native-fixed .ui-footer { | |
top: auto; | |
bottom: 0; | |
} | |
.ui-mobile-touch-overflow.ui-native-fixed .ui-content { | |
padding-top: 2.5em; | |
padding-bottom: 3em; | |
top: 0; | |
bottom: 0; | |
height: auto; | |
position: absolute; | |
} | |
.ui-mobile-touch-overflow.ui-native-fullscreen .ui-content { | |
padding-top: 0; | |
padding-bottom: 0; | |
} | |
.ui-mobile-touch-overflow.ui-native-fullscreen .ui-header, | |
.ui-mobile-touch-overflow.ui-native-fullscreen .ui-footer { | |
opacity: .9; | |
} | |
.ui-native-bars-hidden { | |
display: none; | |
} | |
/* icons sizing */ | |
.ui-icon { width: 18px; height: 18px; } | |
/* fullscreen class on ui-content div */ | |
.ui-fullscreen { } | |
.ui-fullscreen img { max-width: 100%; } | |
/* non-js content hiding */ | |
.ui-nojs { position: absolute; left: -9999px; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.spin { | |
-webkit-transform: rotate(360deg); | |
-webkit-animation-name: spin; | |
-webkit-animation-duration: 1s; | |
-webkit-animation-iteration-count: infinite; | |
-webkit-animation-timing-function: linear; | |
} | |
@-webkit-keyframes spin { | |
from {-webkit-transform: rotate(0deg);} | |
to {-webkit-transform: rotate(360deg);} | |
} | |
/* Transitions from jQtouch (with small modifications): http://www.jqtouch.com/ | |
Built by David Kaneda and maintained by Jonathan Stark. | |
*/ | |
.in, .out { | |
-webkit-animation-timing-function: ease-in-out; | |
-webkit-animation-duration: 350ms; | |
} | |
.slide.out { | |
-webkit-transform: translateX(-100%); | |
-webkit-animation-name: slideouttoleft; | |
} | |
.slide.in { | |
-webkit-transform: translateX(0); | |
-webkit-animation-name: slideinfromright; | |
} | |
.slide.out.reverse { | |
-webkit-transform: translateX(100%); | |
-webkit-animation-name: slideouttoright; | |
} | |
.slide.in.reverse { | |
-webkit-transform: translateX(0); | |
-webkit-animation-name: slideinfromleft; | |
} | |
.slideup.out { | |
-webkit-animation-name: dontmove; | |
z-index: 0; | |
} | |
.slideup.in { | |
-webkit-transform: translateY(0); | |
-webkit-animation-name: slideinfrombottom; | |
z-index: 10; | |
} | |
.slideup.in.reverse { | |
z-index: 0; | |
-webkit-animation-name: dontmove; | |
} | |
.slideup.out.reverse { | |
-webkit-transform: translateY(100%); | |
z-index: 10; | |
-webkit-animation-name: slideouttobottom; | |
} | |
.slidedown.out { | |
-webkit-animation-name: dontmove; | |
z-index: 0; | |
} | |
.slidedown.in { | |
-webkit-transform: translateY(0); | |
-webkit-animation-name: slideinfromtop; | |
z-index: 10; | |
} | |
.slidedown.in.reverse { | |
z-index: 0; | |
-webkit-animation-name: dontmove; | |
} | |
.slidedown.out.reverse { | |
-webkit-transform: translateY(-100%); | |
z-index: 10; | |
-webkit-animation-name: slideouttotop; | |
} | |
@-webkit-keyframes slideinfromright { | |
from { -webkit-transform: translateX(100%); } | |
to { -webkit-transform: translateX(0); } | |
} | |
@-webkit-keyframes slideinfromleft { | |
from { -webkit-transform: translateX(-100%); } | |
to { -webkit-transform: translateX(0); } | |
} | |
@-webkit-keyframes slideouttoleft { | |
from { -webkit-transform: translateX(0); } | |
to { -webkit-transform: translateX(-100%); } | |
} | |
@-webkit-keyframes slideouttoright { | |
from { -webkit-transform: translateX(0); } | |
to { -webkit-transform: translateX(100%); } | |
} | |
@-webkit-keyframes slideinfromtop { | |
from { -webkit-transform: translateY(-100%); } | |
to { -webkit-transform: translateY(0); } | |
} | |
@-webkit-keyframes slideinfrombottom { | |
from { -webkit-transform: translateY(100%); } | |
to { -webkit-transform: translateY(0); } | |
} | |
@-webkit-keyframes slideouttobottom { | |
from { -webkit-transform: translateY(0); } | |
to { -webkit-transform: translateY(100%); } | |
} | |
@-webkit-keyframes slideouttotop { | |
from { -webkit-transform: translateY(0); } | |
to { -webkit-transform: translateY(-100%); } | |
} | |
@-webkit-keyframes fadein { | |
from { opacity: 0; } | |
to { opacity: 1; } | |
} | |
@-webkit-keyframes fadeout { | |
from { opacity: 1; } | |
to { opacity: 0; } | |
} | |
.fade.out { | |
z-index: 0; | |
-webkit-animation-name: fadeout; | |
} | |
.fade.in { | |
opacity: 1; | |
z-index: 10; | |
-webkit-animation-name: fadein; | |
} | |
/* The properties in this rule are only necessary for the 'flip' transition. | |
* We need specify the perspective to create a projection matrix. This will add | |
* some depth as the element flips. The depth number represents the distance of | |
* the viewer from the z-plane. According to the CSS3 spec, 1000 is a moderate | |
* value. | |
*/ | |
.viewport-flip { | |
-webkit-perspective: 1000; | |
position: absolute; | |
} | |
.ui-mobile-viewport-transitioning, | |
.ui-mobile-viewport-transitioning .ui-page { | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
} | |
.flip { | |
-webkit-animation-duration: .65s; | |
-webkit-backface-visibility:hidden; | |
-webkit-transform:translateX(0); /* Needed to work around an iOS 3.1 bug that causes listview thumbs to disappear when -webkit-visibility:hidden is used. */ | |
} | |
.flip.out { | |
-webkit-transform: rotateY(-180deg) scale(.8); | |
-webkit-animation-name: flipouttoleft; | |
} | |
.flip.in { | |
-webkit-transform: rotateY(0) scale(1); | |
-webkit-animation-name: flipinfromleft; | |
} | |
/* Shake it all about */ | |
.flip.out.reverse { | |
-webkit-transform: rotateY(180deg) scale(.8); | |
-webkit-animation-name: flipouttoright; | |
} | |
.flip.in.reverse { | |
-webkit-transform: rotateY(0) scale(1); | |
-webkit-animation-name: flipinfromright; | |
} | |
@-webkit-keyframes flipinfromright { | |
from { -webkit-transform: rotateY(-180deg) scale(.8); } | |
to { -webkit-transform: rotateY(0) scale(1); } | |
} | |
@-webkit-keyframes flipinfromleft { | |
from { -webkit-transform: rotateY(180deg) scale(.8); } | |
to { -webkit-transform: rotateY(0) scale(1); } | |
} | |
@-webkit-keyframes flipouttoleft { | |
from { -webkit-transform: rotateY(0) scale(1); } | |
to { -webkit-transform: rotateY(-180deg) scale(.8); } | |
} | |
@-webkit-keyframes flipouttoright { | |
from { -webkit-transform: rotateY(0) scale(1); } | |
to { -webkit-transform: rotateY(180deg) scale(.8); } | |
} | |
/* Hackish, but reliable. */ | |
@-webkit-keyframes dontmove { | |
from { opacity: 1; } | |
to { opacity: 1; } | |
} | |
.pop { | |
-webkit-transform-origin: 50% 50%; | |
} | |
.pop.in { | |
-webkit-transform: scale(1); | |
opacity: 1; | |
-webkit-animation-name: popin; | |
z-index: 10; | |
} | |
.pop.in.reverse { | |
z-index: 0; | |
-webkit-animation-name: dontmove; | |
} | |
.pop.out.reverse { | |
-webkit-transform: scale(.2); | |
opacity: 0; | |
-webkit-animation-name: popout; | |
z-index: 10; | |
} | |
@-webkit-keyframes popin { | |
from { | |
-webkit-transform: scale(.2); | |
opacity: 0; | |
} | |
to { | |
-webkit-transform: scale(1); | |
opacity: 1; | |
} | |
} | |
@-webkit-keyframes popout { | |
from { | |
-webkit-transform: scale(1); | |
opacity: 1; | |
} | |
to { | |
-webkit-transform: scale(.2); | |
opacity: 0; | |
} | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* content configurations. */ | |
.ui-grid-a, .ui-grid-b, .ui-grid-c, .ui-grid-d { overflow: hidden; } | |
.ui-block-a, .ui-block-b, .ui-block-c, .ui-block-d, .ui-block-e { margin: 0; padding: 0; border: 0; float: left; min-height:1px;} | |
/* grid solo: 100 - single item fallback */ | |
.ui-grid-solo .ui-block-a { width: 100%; float: none; } | |
/* grid a: 50/50 */ | |
.ui-grid-a .ui-block-a, .ui-grid-a .ui-block-b { width: 50%; } | |
.ui-grid-a .ui-block-a { clear: left; } | |
/* grid b: 33/33/33 */ | |
.ui-grid-b .ui-block-a, .ui-grid-b .ui-block-b, .ui-grid-b .ui-block-c { width: 33.333%; } | |
.ui-grid-b .ui-block-a { clear: left; } | |
/* grid c: 25/25/25/25 */ | |
.ui-grid-c .ui-block-a, .ui-grid-c .ui-block-b, .ui-grid-c .ui-block-c, .ui-grid-c .ui-block-d { width: 25%; } | |
.ui-grid-c .ui-block-a { clear: left; } | |
/* grid d: 20/20/20/20/20 */ | |
.ui-grid-d .ui-block-a, .ui-grid-d .ui-block-b, .ui-grid-d .ui-block-c, .ui-grid-d .ui-block-d, .ui-grid-d .ui-block-e { width: 20%; } | |
.ui-grid-d .ui-block-a { clear: left; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
/* fixed page header & footer configuration */ | |
.ui-header, .ui-footer, .ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { position: absolute; overflow: hidden; width: 100%; border-left-width: 0; border-right-width: 0; } | |
.ui-header-fixed, .ui-footer-fixed { | |
z-index: 1000; | |
-webkit-transform: translateZ(0); /* Force header/footer rendering to go through the same rendering pipeline as native page scrolling. */ | |
} | |
.ui-footer-duplicate, .ui-page-fullscreen .ui-fixed-inline { display: none; } | |
.ui-page-fullscreen .ui-header, .ui-page-fullscreen .ui-footer { opacity: .9; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-navbar { overflow: hidden; } | |
.ui-navbar ul, .ui-navbar-expanded ul { list-style:none; padding: 0; margin: 0; position: relative; display: block; border: 0;} | |
.ui-navbar-collapsed ul { float: left; width: 75%; margin-right: -2px; } | |
.ui-navbar-collapsed .ui-navbar-toggle { float: left; width: 25%; } | |
.ui-navbar li.ui-navbar-truncate { position: absolute; left: -9999px; top: -9999px; } | |
.ui-navbar li .ui-btn, .ui-navbar .ui-navbar-toggle .ui-btn { display: block; font-size: 12px; text-align: center; margin: 0; border-right-width: 0; } | |
.ui-navbar li .ui-btn { margin-right: -1px; } | |
.ui-navbar li .ui-btn:last-child { margin-right: 0; } | |
.ui-header .ui-navbar li .ui-btn, .ui-header .ui-navbar .ui-navbar-toggle .ui-btn, | |
.ui-footer .ui-navbar li .ui-btn, .ui-footer .ui-navbar .ui-navbar-toggle .ui-btn { border-top-width: 0; border-bottom-width: 0; } | |
.ui-navbar .ui-btn-inner { padding-left: 2px; padding-right: 2px; } | |
.ui-navbar-noicons li .ui-btn .ui-btn-inner, .ui-navbar-noicons .ui-navbar-toggle .ui-btn-inner { padding-top: .8em; padding-bottom: .9em; } | |
/*expanded page styles*/ | |
.ui-navbar-expanded .ui-btn { margin: 0; font-size: 14px; } | |
.ui-navbar-expanded .ui-btn-inner { padding-left: 5px; padding-right: 5px; } | |
.ui-navbar-expanded .ui-btn-icon-top .ui-btn-inner { padding: 45px 5px 15px; text-align: center; } | |
.ui-navbar-expanded .ui-btn-icon-top .ui-icon { top: 15px; } | |
.ui-navbar-expanded .ui-btn-icon-bottom .ui-btn-inner { padding: 15px 5px 45px; text-align: center; } | |
.ui-navbar-expanded .ui-btn-icon-bottom .ui-icon { bottom: 15px; } | |
.ui-navbar-expanded li .ui-btn .ui-btn-inner { min-height: 2.5em; } | |
.ui-navbar-expanded .ui-navbar-noicons .ui-btn .ui-btn-inner { padding-top: 1.8em; padding-bottom: 1.9em; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-btn { display: block; text-align: center; cursor:pointer; position: relative; margin: .5em 5px; padding: 0; } | |
.ui-btn:focus, .ui-btn:active { outline: none; } | |
.ui-header .ui-btn, .ui-footer .ui-btn, .ui-bar .ui-btn { display: inline-block; font-size: 13px; margin: 0; } | |
.ui-btn-inline { display: inline-block; } | |
.ui-btn-inner { padding: .6em 25px; display: block; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; position: relative; zoom: 1; } | |
.ui-header .ui-btn-inner, .ui-footer .ui-btn-inner, .ui-bar .ui-btn-inner { padding: .4em 8px .5em; } | |
.ui-btn-icon-notext { width: 24px; height: 24px; } | |
.ui-btn-icon-notext .ui-btn-inner { padding: 2px 1px 2px 3px; } | |
.ui-btn-icon-notext .ui-btn-text { position: absolute; left: -999px; } | |
.ui-btn-icon-left .ui-btn-inner { padding-left: 33px; } | |
.ui-header .ui-btn-icon-left .ui-btn-inner, | |
.ui-footer .ui-btn-icon-left .ui-btn-inner, | |
.ui-bar .ui-btn-icon-left .ui-btn-inner { padding-left: 27px; } | |
.ui-btn-icon-right .ui-btn-inner { padding-right: 33px; } | |
.ui-header .ui-btn-icon-right .ui-btn-inner, | |
.ui-footer .ui-btn-icon-right .ui-btn-inner, | |
.ui-bar .ui-btn-icon-right .ui-btn-inner { padding-right: 27px; } | |
.ui-btn-icon-top .ui-btn-inner { padding-top: 33px; } | |
.ui-header .ui-btn-icon-top .ui-btn-inner, | |
.ui-footer .ui-btn-icon-top .ui-btn-inner, | |
.ui-bar .ui-btn-icon-top .ui-btn-inner { padding-top: 27px; } | |
.ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 33px; } | |
.ui-header .ui-btn-icon-bottom .ui-btn-inner, | |
.ui-footer .ui-btn-icon-bottom .ui-btn-inner, | |
.ui-bar .ui-btn-icon-bottom .ui-btn-inner { padding-bottom: 27px; } | |
/*btn icon positioning*/ | |
.ui-btn-icon-notext .ui-icon { display: block; } | |
.ui-btn-icon-left .ui-icon, .ui-btn-icon-right .ui-icon { position: absolute; top: 50%; margin-top: -9px; } | |
.ui-btn-icon-top .ui-icon, .ui-btn-icon-bottom .ui-icon { position: absolute; left: 50%; margin-left: -9px; } | |
.ui-btn-icon-left .ui-icon { left: 10px; } | |
.ui-btn-icon-right .ui-icon { right: 10px; } | |
.ui-btn-icon-top .ui-icon { top: 10px; } | |
.ui-btn-icon-bottom .ui-icon { bottom: 10px; } | |
.ui-header .ui-btn-icon-left .ui-icon, | |
.ui-footer .ui-btn-icon-left .ui-icon, | |
.ui-bar .ui-btn-icon-left .ui-icon { left: 4px; } | |
.ui-header .ui-btn-icon-right .ui-icon, | |
.ui-footer .ui-btn-icon-right .ui-icon, | |
.ui-bar .ui-btn-icon-right .ui-icon { right: 4px; } | |
.ui-header .ui-btn-icon-top .ui-icon, | |
.ui-footer .ui-btn-icon-top .ui-icon, | |
.ui-bar .ui-btn-icon-top .ui-icon { top: 4px; } | |
.ui-header .ui-btn-icon-bottom .ui-icon, | |
.ui-footer .ui-btn-icon-bottom .ui-icon, | |
.ui-bar .ui-btn-icon-bottom .ui-icon { bottom: 4px; } | |
/*hiding native button,inputs */ | |
.ui-btn-hidden { position: absolute; top: 0; left: 0; width: 100%; height: 100%; -webkit-appearance: button; opacity: .1; cursor: pointer; background: transparent; font-size: 1px; border: none; line-height: 999px; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-collapsible { margin: .5em 0; } | |
.ui-collapsible-heading { font-size: 16px; display: block; margin: 0 -8px; padding: 0; border-width: 0 0 1px 0; position: relative; } | |
.ui-collapsible-heading a { text-align: left; margin: 0; } | |
.ui-collapsible-heading a .ui-btn-inner { padding-left: 40px; } | |
.ui-collapsible-heading a span.ui-btn { position: absolute; left: 6px; top: 50%; margin: -12px 0 0 0; width: 20px; height: 20px; padding: 1px 0px 1px 2px; text-indent: -9999px; } | |
.ui-collapsible-heading a span.ui-btn .ui-btn-inner { padding: 10px 0; } | |
.ui-collapsible-heading a span.ui-btn .ui-icon { left: 0; margin-top: -10px; } | |
.ui-collapsible-heading-status { position:absolute; left:-9999px; } | |
.ui-collapsible-content { | |
display: block; | |
margin: 0 -8px; | |
padding: 10px 16px; | |
border-top: none; /* Overrides ui-btn-up-* */ | |
background-image: none; /* Overrides ui-btn-up-* */ | |
font-weight: normal; /* Overrides ui-btn-up-* */ | |
} | |
.ui-collapsible-content-collapsed { display: none; } | |
.ui-collapsible-set { margin: .5em 0; } | |
.ui-collapsible-set .ui-collapsible { margin: -1px 0 0; } | |
/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-controlgroup, fieldset.ui-controlgroup { padding: 0; margin: .5em 0 1em; } | |
.ui-bar .ui-controlgroup { margin: 0 .3em; } | |
.ui-controlgroup-label { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; } | |
.ui-controlgroup-controls { display: block; width: 95%;} | |
.ui-controlgroup li { list-style: none; } | |
.ui-controlgroup-vertical .ui-btn, | |
.ui-controlgroup-vertical .ui-checkbox, .ui-controlgroup-vertical .ui-radio { margin: 0; border-bottom-width: 0; } | |
.ui-controlgroup-vertical .ui-controlgroup-last { border-bottom-width: 1px; } | |
.ui-controlgroup-horizontal { padding: 0; } | |
.ui-controlgroup-horizontal .ui-btn { display: inline-block; margin: 0 -5px 0 0; } | |
.ui-controlgroup-horizontal .ui-checkbox, .ui-controlgroup-horizontal .ui-radio { float: left; margin: 0 -1px 0 0; } | |
.ui-controlgroup-horizontal .ui-checkbox .ui-btn, .ui-controlgroup-horizontal .ui-radio .ui-btn, | |
.ui-controlgroup-horizontal .ui-checkbox:last-child, .ui-controlgroup-horizontal .ui-radio:last-child { margin-right: 0; } | |
.ui-controlgroup-horizontal .ui-controlgroup-last { margin-right: 0; } | |
.ui-controlgroup .ui-checkbox label, .ui-controlgroup .ui-radio label { font-size: 16px; } | |
/* conflicts with listview.. | |
.ui-controlgroup .ui-btn-icon-notext { width: 30px; height: 30px; text-indent: -9999px; } | |
.ui-controlgroup .ui-btn-icon-notext .ui-btn-inner { padding: 5px 6px 5px 5px; } | |
*/ | |
@media all and (min-width: 450px){ | |
.ui-controlgroup-label { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } | |
.ui-controlgroup-controls { width: 60%; display: inline-block; } | |
} /* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-dialog { min-height: 480px; } | |
.ui-dialog .ui-header, .ui-dialog .ui-content, .ui-dialog .ui-footer { margin: 15px; position: relative; } | |
.ui-dialog .ui-header, .ui-dialog .ui-footer { z-index: 10; width: auto; } | |
.ui-dialog .ui-content, .ui-dialog .ui-footer { margin-top: -15px; }/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-checkbox, .ui-radio { position:relative; margin: .2em 0 .5em; z-index: 1; } | |
.ui-checkbox .ui-btn, .ui-radio .ui-btn { margin: 0; text-align: left; z-index: 2; } | |
.ui-checkbox .ui-btn-inner, .ui-radio .ui-btn-inner { white-space: normal; } | |
.ui-checkbox .ui-btn-icon-left .ui-btn-inner,.ui-radio .ui-btn-icon-left .ui-btn-inner { padding-left: 45px; } | |
.ui-checkbox .ui-btn-icon-right .ui-btn-inner, .ui-radio .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } | |
.ui-checkbox .ui-icon, .ui-radio .ui-icon { top: 1.1em; } | |
.ui-checkbox .ui-btn-icon-left .ui-icon, .ui-radio .ui-btn-icon-left .ui-icon {left: 15px; } | |
.ui-checkbox .ui-btn-icon-right .ui-icon, .ui-radio .ui-btn-icon-right .ui-icon {right: 15px; } | |
/* input, label positioning */ | |
.ui-checkbox input,.ui-radio input { position:absolute; left:20px; top:50%; width: 10px; height: 10px; margin:-5px 0 0 0; outline: 0 !important; z-index: 1; }/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-field-contain { padding: 1.5em 0; margin: 0; border-bottom-width: 1px; overflow: visible; } | |
.ui-field-contain:first-child { border-top-width: 0; } | |
@media all and (min-width: 450px){ | |
.ui-field-contain { border-width: 0; padding: 0; margin: 1em 0; } | |
} /* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-select { display: block; position: relative; } | |
.ui-select select { position: absolute; left: -9999px; top: -9999px; } | |
.ui-select .ui-btn { overflow: hidden; } | |
.ui-select .ui-btn select { cursor: pointer; -webkit-appearance: button; left: 0; top:0; width: 100%; min-height: 1.5em; min-height: 100%; height: 3em; max-height: 100%; opacity: 0; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); z-index: 2; } | |
@-moz-document url-prefix() {.ui-select .ui-btn select { opacity: 0.0001; }} | |
.ui-select .ui-btn select.ui-select-nativeonly { opacity: 1; text-indent: 0; } | |
.ui-select .ui-btn-icon-right .ui-btn-inner { padding-right: 45px; } | |
.ui-select .ui-btn-icon-right .ui-icon { right: 15px; } | |
/* labels */ | |
label.ui-select { font-size: 16px; line-height: 1.4; font-weight: normal; margin: 0 0 .3em; display: block; } | |
/*listbox*/ | |
.ui-select .ui-btn-text, .ui-selectmenu .ui-btn-text { display: block; min-height: 1em; } | |
.ui-select .ui-btn-text { text-overflow: ellipsis; overflow: hidden;} | |
.ui-selectmenu { position: absolute; padding: 0; z-index: 100 !important; width: 80%; max-width: 350px; padding: 6px; } | |
.ui-selectmenu .ui-listview { margin: 0; } | |
.ui-selectmenu .ui-btn.ui-li-divider { cursor: default; } | |
.ui-selectmenu-hidden { top: -9999px; left: -9999px; } | |
.ui-selectmenu-screen { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 99; } | |
.ui-screen-hidden, .ui-selectmenu-list .ui-li .ui-icon { display: none; } | |
.ui-selectmenu-list .ui-li .ui-icon { display: block; } | |
.ui-li.ui-selectmenu-placeholder { display: none; } | |
.ui-selectmenu .ui-header .ui-title { margin: 0.6em 46px 0.8em; } | |
@media all and (min-width: 450px){ | |
label.ui-select { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } | |
.ui-select { width: 60%; display: inline-block; } | |
} | |
/* when no placeholder is defined in a multiple select, the header height doesn't even extend past the close button. this shim's content in there */ | |
.ui-selectmenu .ui-header h1:after { content: '.'; visibility: hidden; }/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
label.ui-input-text { font-size: 16px; line-height: 1.4; display: block; font-weight: normal; margin: 0 0 .3em; } | |
input.ui-input-text, textarea.ui-input-text { background-image: none; padding: .4em; line-height: 1.4; font-size: 16px; display: block; width: 95%; } | |
input.ui-input-text { -webkit-appearance: none; } | |
textarea.ui-input-text { height: 50px; -webkit-transition: height 200ms linear; -moz-transition: height 200ms linear; -o-transition: height 200ms linear; transition: height 200ms linear; } | |
.ui-input-search { padding: 0 30px; width: 77%; background-image: none; position: relative; } | |
.ui-icon-searchfield:after { position: absolute; left: 7px; top: 50%; margin-top: -9px; content: ""; width: 18px; height: 18px; opacity: .5; } | |
.ui-input-search input.ui-input-text { border: none; width: 98%; padding: .4em 0; margin: 0; display: block; background: transparent none; outline: 0 !important; } | |
.ui-input-search .ui-input-clear { position: absolute; right: 0; top: 50%; margin-top: -14px; } | |
.ui-input-search .ui-input-clear-hidden { display: none; } | |
/* orientation adjustments - incomplete!*/ | |
@media all and (min-width: 450px){ | |
label.ui-input-text { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0 } | |
input.ui-input-text, | |
textarea.ui-input-text, | |
.ui-input-search { width: 60%; display: inline-block; } | |
.ui-input-search { width: 50%; } | |
.ui-input-search input.ui-input-text { width: 98%; /*echos rule from above*/ } | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
.ui-listview { margin: 0; counter-reset: listnumbering; } | |
.ui-content .ui-listview { margin: -15px; } | |
.ui-content .ui-listview-inset { margin: 1em 0; } | |
.ui-listview, .ui-li { list-style:none; padding:0; } | |
.ui-li, .ui-li.ui-field-contain { display: block; margin:0; position: relative; overflow: visible; text-align: left; border-width: 0; border-top-width: 1px; } | |
.ui-li .ui-btn-text { position: relative; z-index: 1; } | |
.ui-li .ui-btn-text a.ui-link-inherit { text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } | |
.ui-li-divider, .ui-li-static { padding: .5em 15px; font-size: 14px; font-weight: bold; } | |
.ui-li-divider { counter-reset: listnumbering; } | |
ol.ui-listview .ui-link-inherit:before, ol.ui-listview .ui-li-static:before, .ui-li-dec { font-size: .8em; display: inline-block; padding-right: .3em; font-weight: normal;counter-increment: listnumbering; content: counter(listnumbering) ". "; } | |
ol.ui-listview .ui-li-jsnumbering:before { content: "" !important; } /* to avoid chance of duplication */ | |
.ui-listview-inset .ui-li { border-right-width: 1px; border-left-width: 1px; } | |
.ui-li:last-child, .ui-li.ui-field-contain:last-child { border-bottom-width: 1px; } | |
.ui-li>.ui-btn-inner { display: block; position: relative; padding: 0; } | |
.ui-li .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li { padding: .7em 15px .7em 15px; display: block; } | |
.ui-li-has-thumb .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-thumb { min-height: 60px; padding-left: 100px; } | |
.ui-li-has-icon .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-icon { min-height: 20px; padding-left: 40px; } | |
.ui-li-has-count .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-count { padding-right: 45px; } | |
.ui-li-has-arrow .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-arrow { padding-right: 30px; } | |
.ui-li-has-arrow.ui-li-has-count .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-arrow.ui-li-has-count { padding-right: 75px; } | |
.ui-li-heading { font-size: 16px; font-weight: bold; display: block; margin: .6em 0; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } | |
.ui-li-desc { font-size: 12px; font-weight: normal; display: block; margin: -.5em 0 .6em; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; } | |
.ui-li-thumb, .ui-li-icon { position: absolute; left: 1px; top: 0; max-height: 80px; max-width: 80px; } | |
.ui-li-icon { max-height: 40px; max-width: 40px; left: 10px; top: .9em; } | |
.ui-li-thumb, .ui-li-icon, .ui-li-content { float: left; margin-right: 10px; } | |
.ui-li-aside { float: right; width: 50%; text-align: right; margin: .3em 0; } | |
@media all and (min-width: 480px){ | |
.ui-li-aside { width: 45%; } | |
} | |
.ui-li-divider { cursor: default; } | |
.ui-li-has-alt .ui-btn-inner a.ui-link-inherit, .ui-li-static.ui-li-has-alt { padding-right: 95px; } | |
.ui-li-has-count .ui-li-count { position: absolute; font-size: 11px; font-weight: bold; padding: .2em .5em; top: 50%; margin-top: -.9em; right: 38px; } | |
.ui-li-divider .ui-li-count, .ui-li-static .ui-li-count { right: 10px; } | |
.ui-li-has-alt .ui-li-count { right: 55px; } | |
.ui-li-link-alt { position: absolute; width: 40px; height: 100%; border-width: 0; border-left-width: 1px; top: 0; right: 0; margin: 0; padding: 0; z-index: 2; } | |
.ui-li-link-alt .ui-btn { overflow: hidden; position: absolute; right: 8px; top: 50%; margin: -11px 0 0 0; border-bottom-width: 1px; z-index: -1;} | |
.ui-li-link-alt .ui-btn-inner { padding: 0; height: 100%; position: absolute; width: 100%; top: 0; left: 0;} | |
.ui-li-link-alt .ui-btn .ui-icon { right: 50%; margin-right: -9px; } | |
.ui-listview * .ui-btn-inner > .ui-btn > .ui-btn-inner { border-top: 0px; } | |
.ui-listview-filter { border-width: 0; overflow: hidden; margin: -15px -15px 15px -15px } | |
.ui-listview-filter .ui-input-search { margin: 5px; width: auto; display: block; } | |
.ui-listview-filter-inset { margin: -15px -5px -15px -5px; background: transparent; } | |
.ui-li.ui-screen-hidden{display:none;} | |
/* Odd iPad positioning issue. */ | |
@media only screen and (min-device-width: 768px) and (max-device-width: 1024px) { | |
.ui-li .ui-btn-text { overflow: visible; } | |
}/* | |
* jQuery Mobile Framework | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) or GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
label.ui-slider { display: block; } | |
input.ui-slider-input { display: inline-block; width: 50px; } | |
select.ui-slider-switch { display: none; } | |
div.ui-slider { position: relative; display: inline-block; overflow: visible; height: 15px; padding: 0; margin: 0 2% 0 20px; top: 4px; width: 66%; } | |
a.ui-slider-handle { position: absolute; z-index: 10; top: 50%; width: 28px; height: 28px; margin-top: -15px; margin-left: -15px; } | |
a.ui-slider-handle .ui-btn-inner { padding-left: 0; padding-right: 0; } | |
@media all and (min-width: 480px){ | |
label.ui-slider { vertical-align: top; display: inline-block; width: 20%; margin: 0 2% 0 0; } | |
div.ui-slider { width: 45%; } | |
} | |
div.ui-slider-switch { height: 32px; overflow: hidden; margin-left: 0; } | |
div.ui-slider-inneroffset { margin-left: 50%; position: absolute; top: 1px; height: 100%; width: 50%; } | |
a.ui-slider-handle-snapping { -webkit-transition: left 100ms linear; } | |
div.ui-slider-labelbg { position: absolute; top:0; margin: 0; border-width: 0; } | |
div.ui-slider-switch div.ui-slider-labelbg-a { width: 60%; height: 100%; left: 0; } | |
div.ui-slider-switch div.ui-slider-labelbg-b { width: 60%; height: 100%; right: 0; } | |
.ui-slider-switch-a div.ui-slider-labelbg-a, .ui-slider-switch-b div.ui-slider-labelbg-b { z-index: -1; } | |
.ui-slider-switch-a div.ui-slider-labelbg-b, .ui-slider-switch-b div.ui-slider-labelbg-a { z-index: 0; } | |
div.ui-slider-switch a.ui-slider-handle { z-index: 20; width: 101%; height: 32px; margin-top: -18px; margin-left: -101%; } | |
span.ui-slider-label { width: 100%; position: absolute;height: 32px; font-size: 16px; text-align: center; line-height: 2; background: none; border-color: transparent; } | |
span.ui-slider-label-a { left: -100%; margin-right: -1px } | |
span.ui-slider-label-b { right: -100%; margin-left: -1px } | |
<?php | <?php |
header('Content-type: text/css'); | |
ob_start("compress"); | header('Content-type: text/css'); |
function compress($buffer) { | ob_start("compress"); |
function compress($buffer) { | |
/* remove comments */ | /* remove comments */ |
$buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer); | $buffer = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer); |
/* remove tabs, spaces, newlines, etc. */ | /* remove tabs, spaces, newlines, etc. */ |
$buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer); | $buffer = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $buffer); |
return $buffer; | return $buffer; |
} | } |
echo ' | echo ' |
.ui-li-thumb, .ui-li-icon { position: relative; } | .ui-li-thumb, .ui-li-icon { position: relative; } |
.ui-navbar { | .ui-navbar { |
width: 100%; | width: 100%; |
} | } |
.ui-btn-inner { | .ui-btn-inner { |
white-space: normal !important; | white-space: normal !important; |
} | } |
.ui-li-heading { | .ui-li-heading { |
white-space: normal !important; | white-space: normal !important; |
} | } |
.ui-listview-filter { | .ui-listview-filter { |
margin: 0 !important; | margin: 0 !important; |
} | } |
.ui-icon-navigation { | .ui-icon-navigation { |
background-image: url(images/113-navigation.png); | background-image: url(images/113-navigation.png); |
background-position: 1px 0; | background-position: 1px 0; |
} | } |
.ui-icon-beaker { | .ui-icon-beaker { |
background-image: url(images/91-beaker-2.png); | background-image: url(images/91-beaker-2.png); |
background-position: 1px 0; | background-position: 1px 0; |
} | } |
#footer { | #footer { |
text-size: 0.75em; | text-size: 0.75em; |
text-align: center; | text-align: center; |
} | } |
body { | body { |
background-color: #F0F0F0; | background-color: #F0F0F0; |
} | } |
#jqm-homeheader { | #jqm-homeheader { |
text-align: center; | text-align: center; |
} | } |
.viaPoints { | .viaPoints { |
display: none; | display: none; |
text-size: 0.2em; | text-size: 0.2em; |
} | } |
.min-width-480px .viaPoints { | .min-width-480px .viaPoints { |
display: inline; | display: inline; |
} | } |
#extrainfo { | #extrainfo { |
visibility: hidden; | visibility: hidden; |
display: none; | display: none; |
} | } |
#servicewarning { | #servicewarning { |
padding: 1em; | padding: 1em; |
margin-bottom: 0.5em; | margin-bottom: 0.5em; |
text-size: 0.2em; | text-size: 0.2em; |
background-color: #FF9; | background-color: #FF9; |
-moz-border-radius: 15px; | -moz-border-radius: 15px; |
border-radius: 15px; | border-radius: 15px; |
} | } |
#footer { | #footer { |
clear:both; | clear:both; |
text-align:center; | text-align:center; |
} | } |
// source http://webaim.org/techniques/skipnav/ | // source http://webaim.org/techniques/skipnav/ |
#skip a, #skip a:hover, #skip a:visited | #skip a, #skip a:hover, #skip a:visited |
{ | { |
position:absolute; | position:absolute; |
left:0px; | left:0px; |
top:-500px; | top:-500px; |
width:1px; | width:1px; |
height:1px; | height:1px; |
overflow:hidden; | overflow:hidden; |
} | } |
#skip a:active, #skip a:focus | #skip a:active, #skip a:focus |
{ | { |
position:static; | position:static; |
width:auto; | width:auto; |
height:auto; | height:auto; |
}'; | }'; |
//if (false) | //if (false) |
echo ' | echo ' |
// adaptive layout from jQuery Mobile docs site | // adaptive layout from jQuery Mobile docs site |
.type-interior .content-secondary { | .type-interior .content-secondary { |
border-right: 0; | border-right: 0; |
border-left: 0; | border-left: 0; |
margin: 10px -15px 0; | margin: 10px -15px 0; |
background: #fff; | background: #fff; |
border-top: 1px solid #ccc; | border-top: 1px solid #ccc; |
} | } |
.type-home .ui-content { | .type-home .ui-content { |
margin-top: 5px; | margin-top: 5px; |
} | } |
.type-interior .ui-content { | .type-interior .ui-content { |
padding-bottom: 0; | padding-bottom: 0; |
} | } |
.content-secondary .ui-collapsible-contain { | .content-secondary .ui-collapsible-contain { |
padding: 10px 15px; | padding: 10px 15px; |
} | } |
.content-secondary .ui-collapsible-heading { | .content-secondary .ui-collapsible-heading { |
margin: 0 0 30px; | margin: 0 0 30px; |
} | } |
.content-secondary .ui-collapsible-heading-collapsed, | .content-secondary .ui-collapsible-heading-collapsed, |
.content-secondary .ui-collapsible-content { | .content-secondary .ui-collapsible-content { |
padding:0; | padding:0; |
margin: 0; | margin: 0; |
} | } |
/* hires ahoy */ | |
@media all and (min-width: 650px){ | @media all and (min-width: 650px){ |
.content-secondary { | .content-secondary { |
text-align: left; | text-align: left; |
float: left; | float: left; |
width: 45%; | width: 45%; |
background: none; | background: none; |
border-top: 0; | border-top: 0; |
} | } |
.content-secondary, | .content-secondary, |
.type-interior .content-secondary { | .type-interior .content-secondary { |
margin: 30px 0 20px 2%; | margin: 30px 0 20px 2%; |
padding: 20px 4% 0 0; | padding: 20px 4% 0 0; |
background: none; | background: none; |
} | } |
.type-index .content-secondary { | .type-index .content-secondary { |
padding: 0; | padding: 0; |
} | } |
.type-index .content-secondary .ui-listview { | .type-index .content-secondary .ui-listview { |
margin: 0; | margin: 0; |
} | } |
.content-primary { | .content-primary { |
width: 45%; | width: 45%; |
float: right; | float: right; |
margin-top: 30px; | margin-top: 30px; |
margin-right: 1%; | margin-right: 1%; |
padding-right: 1%; | padding-right: 1%; |
} | } |
.content-primary ul:first-child { | .content-primary ul:first-child { |
margin-top: 0; | margin-top: 0; |
} | } |
.type-interior .content-primary { | .type-interior .content-primary { |
padding: 1.5em 6% 3em 0; | padding: 1.5em 6% 3em 0; |
margin: 0; | margin: 0; |
} | } |
/* fix up the collapsibles - expanded on desktop */ | /* fix up the collapsibles - expanded on desktop */ |
.content-secondary .ui-collapsible-heading { | .content-secondary .ui-collapsible-heading { |
display: none; | display: none; |
} | } |
.content-secondary .ui-collapsible-contain { | .content-secondary .ui-collapsible-contain { |
margin:0; | margin:0; |
} | } |
.content-secondary .ui-collapsible-content { | .content-secondary .ui-collapsible-content { |
display: block; | display: block; |
margin: 0; | margin: 0; |
padding: 0; | padding: 0; |
} | } |
.type-interior .content-secondary .ui-li-divider { | .type-interior .content-secondary .ui-li-divider { |
padding-top: 1em; | padding-top: 1em; |
padding-bottom: 1em; | padding-bottom: 1em; |
} | } |
.type-interior .content-secondary { | .type-interior .content-secondary { |
margin: 0; | margin: 0; |
padding: 0; | padding: 0; |
} | } |
} | } |
@media all and (min-width: 750px){ | @media all and (min-width: 750px){ |
.type-home .ui-content, | .type-home .ui-content, |
.type-interior .ui-content { | .type-interior .ui-content { |
background-position: 39%; | background-position: 39%; |
} | } |
.content-secondary { | .content-secondary { |
width: 34%; | width: 34%; |
} | } |
.content-primary { | .content-primary { |
width: 56%; | width: 56%; |
padding-right: 1%; | padding-right: 1%; |
} | } |
.type-interior .ui-content { | .type-interior .ui-content { |
background-position: 34%; | background-position: 34%; |
} | } |
} | } |
@media all and (min-width: 1200px){ | @media all and (min-width: 1200px){ |
.type-home .ui-content{ | .type-home .ui-content{ |
background-position: 38.5%; | background-position: 38.5%; |
} | } |
.type-interior .ui-content { | .type-interior .ui-content { |
background-position: 30%; | background-position: 30%; |
} | } |
.content-secondary { | .content-secondary { |
width: 30%; | width: 30%; |
padding-right:6%; | padding-right:6%; |
margin: 30px 0 20px 5%; | margin: 30px 0 20px 5%; |
} | } |
.type-interior .content-secondary { | .type-interior .content-secondary { |
margin: 0; | margin: 0; |
padding: 0; | padding: 0; |
} | } |
.content-primary { | .content-primary { |
width: 50%; | width: 50%; |
margin-right: 5%; | margin-right: 5%; |
padding-right: 3%; | padding-right: 3%; |
} | } |
.type-interior .content-primary { | .type-interior .content-primary { |
width: 60%; | width: 60%; |
} | } |
}'; | } |
ob_end_flush(); | '; |
ob_end_flush(); | |
?> | ?> |
<?php | <?php |
header('Content-Type: application/vnd.google-earth.kml+xml'); | header('Content-Type: application/vnd.google-earth.kml+xml'); |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
echo '<?xml version="1.0" encoding="UTF-8"?> | echo '<?xml version="1.0" encoding="UTF-8"?> |
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"><Document>'; | <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"><Document>'; |
echo ' | echo ' |
<Style id="yellowLineGreenPoly"> | <Style id="yellowLineGreenPoly"> |
<LineStyle> | <LineStyle> |
<color>7f00ff00</color> | <color>7f00ff00</color> |
<width>4</width> | <width>4</width> |
</LineStyle> | </LineStyle> |
<PolyStyle> | <PolyStyle> |
<color>7f00ffff</color> | <color>7f00ffff</color> |
</PolyStyle> | </PolyStyle> |
</Style>'; | </Style>'; |
$route = getRoute($routeid); | $route = getRoute($routeid); |
echo "\n<Placemark>\n"; | echo "\n<Placemark>\n"; |
$link = curPageURL()."/../trip.php?routeid=".htmlspecialchars ($route["route_id"]); | $link = curPageURL()."/../trip.php?routeid=".htmlspecialchars ($route["route_id"]); |
echo "<name>".$route['route_short_name']."</name>"; | echo "<name>".$route['route_short_name']."</name>"; |
echo '<atom:link href="'.$link.'"/>'; | echo '<atom:link href="'.$link.'"/>'; |
echo '<description><![CDATA[ <a href="'.$link.'">'.$route['route_short_name']." ".$route['route_long_name']."</a>]]> </description>"; | echo '<description><![CDATA[ <a href="'.$link.'">'.$route['route_short_name']." ".$route['route_long_name']."</a>]]> </description>"; |
echo "<styleUrl>#yellowLineGreenPoly</styleUrl>"; | echo "<styleUrl>#yellowLineGreenPoly</styleUrl>"; |
$trips = getRouteTrips($routeid); | $trips = getRouteTrips($routeid); |
echo getTripShape($trips[0]['trip_id']); | echo getTripShape($trips[0]['trip_id']); |
echo "</Placemark>\n</Document></kml>\n"; | echo "</Placemark>\n</Document></kml>\n"; |
?> | ?> |
<?php | <?php |
include ('../include/common.inc.php'); | |
header('Content-type: application/vnd.google-earth.kml+xml'); | header('Content-type: application/vnd.google-earth.kml+xml'); |
//http://wiki.openstreetmap.org/wiki/OpenLayers_Dynamic_KML | //http://wiki.openstreetmap.org/wiki/OpenLayers_Dynamic_KML |
// Creates the KML/XML Document. | // Creates the KML/XML Document. |
$dom = new DOMDocument('1.0', 'UTF-8'); | $dom = new DOMDocument('1.0', 'UTF-8'); |
// Creates the root KML element and appends it to the root document. | // Creates the root KML element and appends it to the root document. |
$node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml'); | $node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml'); |
$parNode = $dom->appendChild($node); | $parNode = $dom->appendChild($node); |
// Creates a KML Document element and append it to the KML element. | // Creates a KML Document element and append it to the KML element. |
$dnode = $dom->createElement('Document'); | $dnode = $dom->createElement('Document'); |
$docNode = $parNode->appendChild($dnode); | $docNode = $parNode->appendChild($dnode); |
if ($suburb != "") $result_stops = getStopsBySuburb($suburb); | if ($suburb != "") $result_stops = getStopsBySuburb($suburb); |
else $result_stops = getStops(); | else $result_stops = getStops(); |
foreach ($result_stops as $stop) { | foreach ($result_stops as $stop) { |
$description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] . " <br>"; | $description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] . " <br>"; |
// Creates a Placemark and append it to the Document. | // Creates a Placemark and append it to the Document. |
$node = $dom->createElement('Placemark'); | $node = $dom->createElement('Placemark'); |
$placeNode = $docNode->appendChild($node); | $placeNode = $docNode->appendChild($node); |
// Creates an id attribute and assign it the value of id column. | // Creates an id attribute and assign it the value of id column. |
$placeNode->setAttribute('id', 'placemark' . $stop['stop_id']); | $placeNode->setAttribute('id', 'placemark' . $stop['stop_id']); |
// Create name, and description elements and assigns them the values of the name and address columns from the results. | // Create name, and description elements and assigns them the values of the name and address columns from the results. |
$nameNode = $dom->createElement('name', htmlentities($stop['stop_name'])); | $nameNode = $dom->createElement('name', htmlentities($stop['stop_name'])); |
$descriptionNode = $dom->createElement('description', $description); | $descriptionNode = $dom->createElement('description', $description); |
$placeNode->appendChild($nameNode); | $placeNode->appendChild($nameNode); |
$placeNode->appendChild($descriptionNode); | $placeNode->appendChild($descriptionNode); |
// Creates a Point element. | // Creates a Point element. |
$pointNode = $dom->createElement('Point'); | $pointNode = $dom->createElement('Point'); |
$placeNode->appendChild($pointNode); | $placeNode->appendChild($pointNode); |
// Creates a coordinates element and gives it the value of the lng and lat columns from the results. | // Creates a coordinates element and gives it the value of the lng and lat columns from the results. |
$coorStr = $stop['stop_lon'] . ',' . $stop['stop_lat']; | $coorStr = $stop['stop_lon'] . ',' . $stop['stop_lat']; |
$coorNode = $dom->createElement('coordinates', $coorStr); | $coorNode = $dom->createElement('coordinates', $coorStr); |
$pointNode->appendChild($coorNode); | $pointNode->appendChild($coorNode); |
} | } |
$kmlOutput = $dom->saveXML(); | $kmlOutput = $dom->saveXML(); |
echo $kmlOutput; | echo $kmlOutput; |
?> | ?> |
<?php | <?php |
function getScheme() | require $basePath.'lib/openid.php'; |
{ | $openid = new LightOpenID($_SERVER['HTTP_HOST']); |
$scheme = 'http'; | |
if (isset($_SERVER['HTTPS']) and $_SERVER['HTTPS'] == 'on') { | |
$scheme .= 's'; | |
} | |
return $scheme; | |
} | |
function getTrustRoot() | |
{ | |
return sprintf("%s://%s:%s%s/", | |
getScheme(), $_SERVER['SERVER_NAME'], | |
$_SERVER['SERVER_PORT'], | |
dirname($_SERVER['PHP_SELF'])); | |
} | |
// Includes required files | |
set_include_path(get_include_path() . PATH_SEPARATOR . $labsPath."lib/openid-php/"); | |
require_once "Auth/OpenID/Consumer.php"; | |
require_once "Auth/OpenID/FileStore.php"; | |
require_once "Auth/OpenID/AX.php"; | |
function login() | function login() |
{ | { |
// Just tested this with/for Google, needs trying with others ... | global $openid; |
$oid_identifier = 'https://www.google.com/accounts/o8/id'; | if(!$openid->mode) { |
// Create file storage area for OpenID data | $openid->required = array('contact/email'); |
$store = new Auth_OpenID_FileStore('lib/openid-php/oid_store'); | $openid->identity = 'https://www.google.com/accounts/o8/id'; |
// Create OpenID consumer | header('Location: ' . $openid->authUrl()); |
$consumer = new Auth_OpenID_Consumer($store); | } |
// Create an authentication request to the OpenID provider | |
$auth = $consumer -> begin($oid_identifier); | |
// Create attribute request object | |
// See http://code.google.com/apis/accounts/docs/OpenID.html#Parameters for parameters | |
// Usage: make($type_uri, $count=1, $required=false, $alias=null) | |
$attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/contact/email', 2, 1, 'email'); | |
$attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/namePerson/first', 1, 1, 'firstname'); | |
$attribute[] = Auth_OpenID_AX_AttrInfo :: make('http://axschema.org/namePerson/last', 1, 1, 'lastname'); | |
// Create AX fetch request | |
$ax = new Auth_OpenID_AX_FetchRequest; | |
// Add attributes to AX fetch request | |
foreach($attribute as $attr) { | |
$ax -> add($attr); | |
} | |
// Add AX fetch request to authentication request | |
$auth -> addExtension($ax); | |
$_SESSION['returnURL'] = curPageURL(); | |
// Redirect to OpenID provider for authentication | |
$url = $auth -> redirectURL(getTrustRoot(), $_SESSION['returnURL']); | |
header('Location: ' . $url); | |
} | } |
function auth() | function auth() |
{ | { |
if ($_SESSION['authed'] == true) return true; | if ($_SESSION['authed'] == true) return true; |
global $openid; | |
// Create file storage area for OpenID data | |
$store = new Auth_OpenID_FileStore('lib/openid-php/oid_store'); | if($openid->mode) { |
// Create OpenID consumer | $attr = $openid->getAttributes(); |
$consumer = new Auth_OpenID_Consumer($store); | if ($attr["contact/email"] != "maxious@gmail.com") { |
// Create an authentication request to the OpenID provider | |
$response = $consumer -> complete($_SESSION['returnURL']); | |
if ($response -> status == Auth_OpenID_SUCCESS) { | |
// Get registration informations | |
$ax = new Auth_OpenID_AX_FetchResponse(); | |
$obj = $ax -> fromSuccessResponse($response); | |
$email = $obj -> data['http://axschema.org/contact/email'][0]; | |
var_dump($email); | |
if ($email != "maxious@gmail.com") { | |
die("Access Denied"); | die("Access Denied"); |
} else { | } else { |
$_SESSION['authed'] = true; | $_SESSION['authed'] = true; |
} | } |
} else { | } else { |
login(); | login(); |
} | } |
} | } |
if ($_REQUEST['janrain_nonce']) auth(); | |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
if (php_uname('n') == "actbus-www") { | if (php_uname('n') == "actbus-www") { |
$conn = new PDO("pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=bus-main.lambdacomplex.org"); | $conn = new PDO("pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=bus-main.lambdacomplex.org"); |
} | } else if (isDebugServer()) { |
else if (isDebugServer()) { | $conn = new PDO("pgsql:dbname=transitdata;user=postgres;password=snmc;host=localhost"); |
$conn = new PDO("pgsql:dbname=transitdata;user=postgres;password=snmc;host=localhost"); | } else { |
} | $conn = new PDO("pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=localhost"); |
else { | |
$conn = new PDO("pgsql:dbname=transitdata;user=transitdata;password=transitdata;host=localhost"); | |
} | } |
if (!$conn) { | if (!$conn) { |
die("A database error occurred.\n"); | die("A database error occurred.\n"); |
} | } |
function databaseError($errMsg) | |
{ | function databaseError($errMsg) { |
die($errMsg); | die($errMsg); |
} | } |
include ('db/route-dao.inc.php'); | include ('db/route-dao.inc.php'); |
include ('db/trip-dao.inc.php'); | include ('db/trip-dao.inc.php'); |
include ('db/stop-dao.inc.php'); | include ('db/stop-dao.inc.php'); |
include ('db/servicealert-dao.inc.php'); | include ('db/servicealert-dao.inc.php'); |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
// SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',') | // SELECT array_to_string(array(SELECT REPLACE(name_2006, ',', '\,') as name FROM suburbs order by name), ',') |
$suburbs = explode(",", "Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla"); | $suburbs = explode(",", "Acton,Ainslie,Amaroo,Aranda,Banks,Barton,Belconnen,Bonner,Bonython,Braddon,Bruce,Calwell,Campbell,Chapman,Charnwood,Chifley,Chisholm,City,Conder,Cook,Curtin,Deakin,Dickson,Downer,Duffy,Dunlop,Evatt,Fadden,Farrer,Fisher,Florey,Flynn,Forrest,Franklin,Fraser,Fyshwick,Garran,Gilmore,Giralang,Gordon,Gowrie,Greenway,Griffith,Gungahlin,Hackett,Hall,Harrison,Hawker,Higgins,Holder,Holt,Hughes,Hume,Isaacs,Isabella Plains,Kaleen,Kambah,Kingston,Latham,Lawson,Lyneham,Lyons,Macarthur,Macgregor,Macquarie,Mawson,McKellar,Melba,Mitchell,Monash,Narrabundah,Ngunnawal,Nicholls,Oaks Estate,O'Connor,O'Malley,Oxley,Page,Palmerston,Parkes,Pearce,Phillip,Pialligo,Red Hill,Reid,Richardson,Rivett,Russell,Scullin,Spence,Stirling,Symonston,Tharwa,Theodore,Torrens,Turner,Wanniassa,Waramanga,Watson,Weetangera,Weston,Yarralumla"); |
function staticmap($mapPoints, $zoom = 0, $markerImage = "iconb", $collapsible = true, $twotone = false) | |
{ | function staticmap($mapPoints, $collapsible = true, $twotone = false, $path = false, $numbered = false) { |
global $labsPath; | |
$width = 300; | $markers = ""; |
$height = 300; | $height = 300; |
$metersperpixel[9] = 305.492 * $width; | $width = $height; |
$metersperpixel[10] = 152.746 * $width; | $index = 0; |
$metersperpixel[11] = 76.373 * $width; | if (sizeof($mapPoints) < 1) |
$metersperpixel[12] = 38.187 * $width; | return "map error"; |
$metersperpixel[13] = 19.093 * $width; | if (sizeof($mapPoints) === 1) { |
$metersperpixel[14] = 9.547 * $width; | $markers = "markers={$mapPoints[0][0]},{$mapPoints[0][1]}"; |
$metersperpixel[15] = 4.773 * $width; | } else { |
//$metersperpixel[16] = 2.387 * $width; | if (!$numbered) { |
// $metersperpixel[17]=1.193*$width; | $markers = "markers="; |
$center = ""; | } |
$markers = ""; | if ($path) { |
$mapwidthinmeters = 50; | $markers.= "markers={$mapPoints[0][0]},{$mapPoints[0][1]}&path="; |
if (sizeof($mapPoints) < 1) return "map error"; | } |
if (sizeof($mapPoints) === 1) { | foreach ($mapPoints as $index => $mapPoint) { |
if ($zoom == 0) $zoom = 14; | if ($twotone && $index == 0) { |
$markers.= "{$mapPoints[0][0]},{$mapPoints[0][1]},$markerimage"; | $markers = "markerd=color:red|".$mapPoint[0] . "," . $mapPoint[1]."&markers="; |
$center = "{$mapPoints[0][0]},{$mapPoints[0][1]}"; | } else { |
} | if ($numbered) { |
else { | $label = ($index > 9 ? 9 : $index); |
foreach ($mapPoints as $index => $mapPoint) { | $markers.= "markers=label:$label|" . $mapPoint[0] . "," . $mapPoint[1]; |
if ($twotone && $index == 0) { | if ($index + 1 != sizeof($mapPoints)) { |
$markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . "iconr" . ($index + 1); | $markers.= "&"; |
$center = "{$mapPoints[0][0]},{$mapPoints[0][1]}"; | } |
} | } else { |
else { | $markers.= $mapPoint[0] . "," . $mapPoint[1]; |
$markers.= $mapPoint[0] . "," . $mapPoint[1] . "," . $markerImage . ($index + 1); | if ($index + 1 != sizeof($mapPoints)) { |
} | $markers.= "|"; |
if ($index + 1 != sizeof($mapPoints)) $markers.= "|"; | } |
$dist = distance($mapPoints[0][0], $mapPoint[0][1], $mapPoint[0], $mapPoint[1]); | } |
$mapwidthinmeters = ($dist > $mapwidthinmeters ? $dist : $mapwidthinmeters); | $index++; |
$totalLat+= $mapPoint[0]; | } |
$totalLon+= $mapPoint[1]; | } |
} | } |
if ($zoom == 0) { | $output = ""; |
$mapwidthinmeters = distance($minlat, $minlon, $minlat, $maxlon); | if ($collapsible) |
foreach (array_reverse($metersperpixel, true) as $zoomLevel => $maxdistance) { | $output.= '<div class="map" data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>'; |
if ($zoom == 0 && $mapwidthinmeters * 1.5 < ($maxdistance)) $zoom = $zoomLevel; | if (isIOSDevice()) $output.= '<img class="hiresmap" src="http://maps.googleapis.com/maps/api/staticmap?size=' . $width . 'x' . $height . '&' . $markers . '&scale=2&sensor=true" width=' . $width . ' height=' . $height . '>'; |
} | else $output.= '<img class="lowresmap" src="http://maps.googleapis.com/maps/api/staticmap?size=' . $width . 'x' . $height . '&' . $markers . '&scale=1&format=jpg&sensor=true" width=' . $width . ' height=' . $height . '>'; |
} | |
$center = $totalLat / sizeof($mapPoints) . "," . $totalLon / sizeof($mapPoints); | if ($collapsible) |
} | $output.= '</div>'; |
$output = ""; | return $output; |
if ($collapsible) $output.= '<div class="map" data-role="collapsible" data-collapsed="true"><h3>Open Map...</h3>'; | |
$output.= '<img class="map" src="' . curPageURL() . '/' . $labsPath . '/lib/staticmaplite/staticmap.php?center=' . $center . '&zoom=' . $zoom . '&size=' . $width . 'x' . $height . '&markers=' . $markers . '" width=' . $width . ' height=' . $height . '>'; | |
if ($collapsible) $output.= '</div>'; | |
return $output; | |
} | } |
function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) | |
{ | function distance($lat1, $lng1, $lat2, $lng2, $roundLargeValues = false) { |
$pi80 = M_PI / 180; | $pi80 = M_PI / 180; |
$lat1*= $pi80; | $lat1*= $pi80; |
$lng1*= $pi80; | $lng1*= $pi80; |
$lat2*= $pi80; | $lat2*= $pi80; |
$lng2*= $pi80; | $lng2*= $pi80; |
$r = 6372.797; // mean radius of Earth in km | $r = 6372.797; // mean radius of Earth in km |
$dlat = $lat2 - $lat1; | $dlat = $lat2 - $lat1; |
$dlng = $lng2 - $lng1; | $dlng = $lng2 - $lng1; |
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); | $a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2); |
$c = 2 * atan2(sqrt($a) , sqrt(1 - $a)); | $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); |
$km = $r * $c; | $km = $r * $c; |
if ($roundLargeValues) { | if ($roundLargeValues) { |
if ($km < 1) return floor($km * 1000); | if ($km < 1) |
else return round($km, 2) . "k"; | return floor($km * 1000); |
} | else |
else return floor($km * 1000); | return round($km, 2) . "k"; |
} | |
else | |
return floor($km * 1000); | |
} | } |
function decodePolylineToArray($encoded) | |
{ | function decodePolylineToArray($encoded) { |
// source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 | // source: http://latlongeeks.com/forum/viewtopic.php?f=4&t=5 |
$length = strlen($encoded); | $length = strlen($encoded); |
$index = 0; | $index = 0; |
$points = array(); | $points = array(); |
$lat = 0; | $lat = 0; |
$lng = 0; | $lng = 0; |
while ($index < $length) { | while ($index < $length) { |
// Temporary variable to hold each ASCII byte. | // Temporary variable to hold each ASCII byte. |
$b = 0; | $b = 0; |
// The encoded polyline consists of a latitude value followed by a | // The encoded polyline consists of a latitude value followed by a |
// longitude value. They should always come in pairs. Read the | // longitude value. They should always come in pairs. Read the |
// latitude value first. | // latitude value first. |
$shift = 0; | $shift = 0; |
$result = 0; | $result = 0; |
do { | do { |
// The `ord(substr($encoded, $index++))` statement returns the ASCII | // The `ord(substr($encoded, $index++))` statement returns the ASCII |
// code for the character at $index. Subtract 63 to get the original | // code for the character at $index. Subtract 63 to get the original |
// value. (63 was added to ensure proper ASCII characters are displayed | // value. (63 was added to ensure proper ASCII characters are displayed |
// in the encoded polyline string, which is `human` readable) | // in the encoded polyline string, which is `human` readable) |
$b = ord(substr($encoded, $index++)) - 63; | $b = ord(substr($encoded, $index++)) - 63; |
// AND the bits of the byte with 0x1f to get the original 5-bit `chunk. | // AND the bits of the byte with 0x1f to get the original 5-bit `chunk. |
// Then left shift the bits by the required amount, which increases | // Then left shift the bits by the required amount, which increases |
// by 5 bits each time. | // by 5 bits each time. |
// OR the value into $results, which sums up the individual 5-bit chunks | // OR the value into $results, which sums up the individual 5-bit chunks |
// into the original value. Since the 5-bit chunks were reversed in | // into the original value. Since the 5-bit chunks were reversed in |
// order during encoding, reading them in this way ensures proper | // order during encoding, reading them in this way ensures proper |
// summation. | // summation. |
$result|= ($b & 0x1f) << $shift; | $result|= ($b & 0x1f) << $shift; |
$shift+= 5; | $shift+= 5; |
} | } |
// Continue while the read byte is >= 0x20 since the last `chunk` | // Continue while the read byte is >= 0x20 since the last `chunk` |
// was not OR'd with 0x20 during the conversion process. (Signals the end) | // was not OR'd with 0x20 during the conversion process. (Signals the end) |
while ($b >= 0x20); | while ($b >= 0x20); |
// Check if negative, and convert. (All negative values have the last bit | // Check if negative, and convert. (All negative values have the last bit |
// set) | // set) |
$dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); | $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1)); |
// Compute actual latitude since value is offset from previous value. | // Compute actual latitude since value is offset from previous value. |
$lat+= $dlat; | $lat+= $dlat; |
// The next values will correspond to the longitude for this point. | // The next values will correspond to the longitude for this point. |
$shift = 0; | $shift = 0; |
$result = 0; | $result = 0; |
do { | do { |
$b = ord(substr($encoded, $index++)) - 63; | $b = ord(substr($encoded, $index++)) - 63; |
$result|= ($b & 0x1f) << $shift; | $result|= ($b & 0x1f) << $shift; |
$shift+= 5; | $shift+= 5; |
} while ($b >= 0x20); | } while ($b >= 0x20); |
$dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); | $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1)); |
$lng+= $dlng; | $lng+= $dlng; |
// The actual latitude and longitude values were multiplied by | // The actual latitude and longitude values were multiplied by |
// 1e5 before encoding so that they could be converted to a 32-bit | // 1e5 before encoding so that they could be converted to a 32-bit |
// integer representation. (With a decimal accuracy of 5 places) | // integer representation. (With a decimal accuracy of 5 places) |
// Convert back to original values. | // Convert back to original values. |
$points[] = array( | $points[] = array( |
$lat * 1e-5, | $lat * 1e-5, |
$lng * 1e-5 | $lng * 1e-5 |
); | ); |
} | } |
return $points; | return $points; |
} | } |
function geocode($query, $giveOptions) | |
{ | function geocode($query, $giveOptions) { |
global $cloudmadeAPIkey; | global $cloudmadeAPIkey; |
$url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; | $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?query=" . urlencode($query) . "&bbox=-35.5,149.00,-35.15,149.1930&return_location=true&bbox_only=true"; |
$contents = json_decode(getPage($url)); | $contents = json_decode(getPage($url)); |
if ($giveOptions) return $contents->features; | if ($giveOptions) |
elseif (isset($contents->features[0]->centroid)) return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; | return $contents->features; |
else return ""; | elseif (isset($contents->features[0]->centroid)) |
return $contents->features[0]->centroid->coordinates[0] . "," . $contents->features[0]->centroid->coordinates[1]; | |
else | |
return ""; | |
} | } |
function reverseGeocode($lat, $lng) | |
{ | function reverseGeocode($lat, $lng) { |
global $cloudmadeAPIkey; | global $cloudmadeAPIkey; |
$url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; | $url = "http://geocoding.cloudmade.com/$cloudmadeAPIkey/geocoding/v2/find.js?around=" . $lat . "," . $lng . "&distance=closest&object_type=road"; |
$contents = json_decode(getPage($url)); | $contents = json_decode(getPage($url)); |
return $contents->features[0]->properties->name; | return $contents->features[0]->properties->name; |
} | } |
?> | ?> |
<?php | <?php |
function getPage($url) | |
{ | /* |
debug($url, "json"); | * Copyright 2010,2011 Alexander Sadleir |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | Licensed under the Apache License, Version 2.0 (the "License"); |
curl_setopt($ch, CURLOPT_HEADER, 0); | you may not use this file except in compliance with the License. |
curl_setopt($ch, CURLOPT_TIMEOUT, 45); | You may obtain a copy of the License at |
$page = curl_exec($ch); | |
if (curl_errno($ch)) { | http://www.apache.org/licenses/LICENSE-2.0 |
echo "<font color=red> Database temporarily unavailable: "; | |
echo curl_errno($ch) . " " . curl_error($ch); | Unless required by applicable law or agreed to in writing, software |
if (isDebug()) { | distributed under the License is distributed on an "AS IS" BASIS, |
echo $url; | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
} | See the License for the specific language governing permissions and |
echo "</font><br>"; | limitations under the License. |
} | */ |
curl_close($ch); | |
debug(print_r($page,true),"json"); | function getPage($url) { |
return $page; | debug($url, "json"); |
$ch = curl_init($url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 45); | |
$page = curl_exec($ch); | |
if (curl_errno($ch)) { | |
echo "<font color=red> Database temporarily unavailable: "; | |
echo curl_errno($ch) . " " . curl_error($ch); | |
if (isDebug()) { | |
echo $url; | |
} | |
echo "</font><br>"; | |
} | |
curl_close($ch); | |
debug(print_r($page, true), "json"); | |
return $page; | |
} | } |
function curPageURL() | |
{ | function curPageURL() { |
$isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"); | $isHTTPS = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"); |
$port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443"))); | $port = (isset($_SERVER["SERVER_PORT"]) && ((!$isHTTPS && $_SERVER["SERVER_PORT"] != "80") || ($isHTTPS && $_SERVER["SERVER_PORT"] != "443"))); |
$port = ($port) ? ':' . $_SERVER["SERVER_PORT"] : ''; | $port = ($port) ? ':' . $_SERVER["SERVER_PORT"] : ''; |
$url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"] . $port . htmlentities(dirname($_SERVER['PHP_SELF']) , ENT_QUOTES); | $url = ($isHTTPS ? 'https://' : 'http://') . $_SERVER["SERVER_NAME"] . $port . htmlentities(dirname($_SERVER['PHP_SELF']), ENT_QUOTES); |
return $url; | return $url; |
} | } |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
if (isset($_REQUEST['firstLetter'])) { | if (isset($_REQUEST['firstLetter'])) { |
$firstLetter = filter_var($_REQUEST['firstLetter'], FILTER_SANITIZE_STRING); | $firstLetter = filter_var($_REQUEST['firstLetter'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['bysuburbs'])) { | if (isset($_REQUEST['bysuburbs'])) { |
$bysuburbs = true; | $bysuburbs = true; |
} | } |
if (isset($_REQUEST['bynumber'])) { | if (isset($_REQUEST['bynumber'])) { |
$bynumber = true; | $bynumber = true; |
} | } |
if (isset($_REQUEST['allstops'])) { | if (isset($_REQUEST['allstops'])) { |
$allstops = true; | $allstops = true; |
} | } |
if (isset($_REQUEST['nearby'])) { | if (isset($_REQUEST['nearby'])) { |
$nearby = true; | $nearby = true; |
} | } |
if (isset($_REQUEST['suburb'])) { | if (isset($_REQUEST['suburb'])) { |
$suburb = $_REQUEST['suburb']; | $suburb = $_REQUEST['suburb']; |
} | } |
$pageKey = filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); | if (isset($_REQUEST['pageKey'])) { |
$lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | $pageKey = filter_var($_REQUEST['pageKey'], FILTER_SANITIZE_NUMBER_INT); |
$lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | } |
$max_distance = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_INT); | if (isset($_REQUEST['lat'])) { |
$lat = filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | |
} | |
if (isset($_REQUEST['lon'])) { | |
$lon = filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); | |
} | |
if (isset($_REQUEST['radius'])) { | |
$max_distance = filter_var($_REQUEST['radius'], FILTER_SANITIZE_NUMBER_INT); | |
} | |
if (isset($_REQUEST['numberSeries'])) { | if (isset($_REQUEST['numberSeries'])) { |
$numberSeries = filter_var($_REQUEST['numberSeries'], FILTER_SANITIZE_NUMBER_INT); | $numberSeries = filter_var($_REQUEST['numberSeries'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['routeDestination'])) { | if (isset($_REQUEST['routeDestination'])) { |
$routeDestination = urldecode(filter_var($_REQUEST['routeDestination'], FILTER_SANITIZE_ENCODED)); | $routeDestination = urldecode(filter_var($_REQUEST['routeDestination'], FILTER_SANITIZE_ENCODED)); |
} | } |
if (isset($_REQUEST['stopcode'])) { | if (isset($_REQUEST['stopcode'])) { |
$stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING); | $stopcode = filter_var($_REQUEST['stopcode'], FILTER_SANITIZE_STRING); |
} | } |
if (isset($_REQUEST['stopids'])) { | if (isset($_REQUEST['stopids'])) { |
$stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING)); | $stopids = explode(",", filter_var($_REQUEST['stopids'], FILTER_SANITIZE_STRING)); |
} | } |
if (isset($_REQUEST['tripid'])) { | if (isset($_REQUEST['tripid'])) { |
$tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_NUMBER_INT); | $tripid = filter_var($_REQUEST['tripid'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['stopid'])) { | if (isset($_REQUEST['stopid'])) { |
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); | $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['routeid'])) { | if (isset($_REQUEST['routeid'])) { |
$routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT); | $routeid = filter_var($_REQUEST['routeid'], FILTER_SANITIZE_NUMBER_INT); |
} | } |
if (isset($_REQUEST['geolocate'])) { | if (isset($_REQUEST['geolocate'])) { |
$geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); | $geolocate = filter_var($_REQUEST['geolocate'], FILTER_SANITIZE_URL); |
} | } |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
// you have to open the session to be able to modify or remove it | // you have to open the session to be able to modify or remove it |
session_start(); | session_start(); |
if (isset($_REQUEST['service_period'])) { | if (isset($_REQUEST['service_period'])) { |
$_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); | $_SESSION['service_period'] = filter_var($_REQUEST['service_period'], FILTER_SANITIZE_STRING); |
sessionUpdated(); | sessionUpdated(); |
} | } |
if (isset($_REQUEST['time'])) { | if (isset($_REQUEST['time'])) { |
$_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); | $_SESSION['time'] = filter_var($_REQUEST['time'], FILTER_SANITIZE_STRING); |
sessionUpdated(); | sessionUpdated(); |
} | } |
if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { | if (isset($_REQUEST['geolocate']) && $_REQUEST['geolocate'] != "Enter co-ordinates or address here") { |
$geocoded = false; | $geocoded = false; |
if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { | if (isset($_REQUEST['lat']) && isset($_REQUEST['lon'])) { |
$_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); | $_SESSION['lat'] = trim(filter_var($_REQUEST['lat'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); |
$_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); | $_SESSION['lon'] = trim(filter_var($_REQUEST['lon'], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION)); |
} | } else { |
else { | if (startsWith($geolocate, "-")) { |
if (startsWith($geolocate, "-")) { | $locateparts = explode(",", $geolocate); |
$locateparts = explode(",", $geolocate); | $_SESSION['lat'] = $locateparts[0]; |
$_SESSION['lat'] = $locateparts[0]; | $_SESSION['lon'] = $locateparts[1]; |
$_SESSION['lon'] = $locateparts[1]; | } else if (strpos($geolocate, "(") !== false) { |
} | $geoParts = explode("(", $geolocate); |
else if (strpos($geolocate, "(") !== false) { | $locateparts = explode(",", str_replace(")", "", $geoParts[1])); |
$geoParts = explode("(", $geolocate); | $_SESSION['lat'] = $locateparts[0]; |
$locateparts = explode(",", str_replace(")", "",$geoParts[1])); | $_SESSION['lon'] = $locateparts[1]; |
$_SESSION['lat'] = $locateparts[0]; | } else { |
$_SESSION['lon'] = $locateparts[1]; | $contents = geocode($geolocate, true); |
} | print_r($contents); |
else { | if (isset($contents[0]->centroid)) { |
$contents = geocode($geolocate, true); | $geocoded = true; |
print_r($contents); | $_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; |
if (isset($contents[0]->centroid)) { | $_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; |
$geocoded = true; | } else { |
$_SESSION['lat'] = $contents[0]->centroid->coordinates[0]; | $_SESSION['lat'] = ""; |
$_SESSION['lon'] = $contents[0]->centroid->coordinates[1]; | $_SESSION['lon'] = ""; |
} | } |
else { | } |
$_SESSION['lat'] = ""; | } |
$_SESSION['lon'] = ""; | sessionUpdated(); |
} | |
} | |
} | |
sessionUpdated(); | |
} | } |
function sessionUpdated() | |
{ | function sessionUpdated() { |
$_SESSION['lastUpdated'] = time(); | $_SESSION['lastUpdated'] = time(); |
} | } |
// timeoutSession | // timeoutSession |
$TIMEOUT_LIMIT = 60 * 5; // 5 minutes | $TIMEOUT_LIMIT = 60 * 5; // 5 minutes |
if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated'] + $TIMEOUT_LIMIT < time()) { | if (isset($_SESSION['lastUpdated']) && $_SESSION['lastUpdated'] + $TIMEOUT_LIMIT < time()) { |
debug("Session timeout " . ($_SESSION['lastUpdated'] + $TIMEOUT_LIMIT) . ">" . time() , "session"); | debug("Session timeout " . ($_SESSION['lastUpdated'] + $TIMEOUT_LIMIT) . ">" . time(), "session"); |
session_destroy(); | session_destroy(); |
session_start(); | session_start(); |
} | } |
//debug(print_r($_SESSION, true) , "session"); | //debug(print_r($_SESSION, true) , "session"); |
function current_time() | function current_time() { |
{ | return ($_SESSION['time'] ? $_SESSION['time'] : date("H:i:s")); |
return ($_SESSION['time'] ? $_SESSION['time'] : date("H:i:s")); | |
} | } |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
// Copyright 2009 Google Inc. All Rights Reserved. | // Copyright 2009 Google Inc. All Rights Reserved. |
$GA_ACCOUNT = "MO-22173039-1"; | $GA_ACCOUNT = "MO-22173039-1"; |
$GA_PIXEL = "/lib/ga.php"; | $GA_PIXEL = "/lib/ga.php"; |
function googleAnalyticsGetImageUrl() | |
{ | function googleAnalyticsGetImageUrl() { |
global $GA_ACCOUNT, $GA_PIXEL; | global $GA_ACCOUNT, $GA_PIXEL; |
//if (stristr($_SERVER['HTTP_USER_AGENT'], 'Googlebot') return ""; | //if (stristr($_SERVER['HTTP_USER_AGENT'], 'Googlebot') return ""; |
$url = ""; | $url = ""; |
$url.= $GA_PIXEL . "?"; | $url.= $GA_PIXEL . "?"; |
$url.= "utmac=" . $GA_ACCOUNT; | $url.= "utmac=" . $GA_ACCOUNT; |
$url.= "&utmn=" . rand(0, 0x7fffffff); | $url.= "&utmn=" . rand(0, 0x7fffffff); |
$referer = $_SERVER["HTTP_REFERER"]; | $referer = $_SERVER["HTTP_REFERER"]; |
$query = $_SERVER["QUERY_STRING"]; | $query = $_SERVER["QUERY_STRING"]; |
$path = $_SERVER["REQUEST_URI"]; | $path = $_SERVER["REQUEST_URI"]; |
if (empty($referer)) { | if (empty($referer)) { |
$referer = "-"; | $referer = "-"; |
} | } |
$url.= "&utmr=" . urlencode($referer); | $url.= "&utmr=" . urlencode($referer); |
if (!empty($path)) { | if (!empty($path)) { |
$url.= "&utmp=" . urlencode($path); | $url.= "&utmp=" . urlencode($path); |
} | } |
$url.= "&guid=ON"; | $url.= "&guid=ON"; |
return str_replace("&", "&", $url); | return str_replace("&", "&", $url); |
} | } |
function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false) | |
{ | function include_header($pageTitle, $pageType, $opendiv = true, $geolocate = false, $datepicker = false) { |
global $labsPath,$serviceAlertsEnabled; | global $basePath, $GTFSREnabled; |
echo ' | echo ' |
<!DOCTYPE html> | <!DOCTYPE html> |
<html lang="en"> | <html lang="en"> |
<head> | <head> |
<meta charset="UTF-8"> | <meta charset="UTF-8"> |
<meta name="viewport" content="width=device-width, initial-scale=1"> | <meta name="viewport" content="width=device-width, initial-scale=1"> |
<title>' . $pageTitle . '</title> | <title>' . $pageTitle . ' - Canberra Bus Timetable</title> |
<meta name="google-site-verification" content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" /> | <meta name="google-site-verification" content="-53T5Qn4TB_de1NyfR_ZZkEVdUNcNFSaYKSFkWKx-sY" /> |
<link rel="dns-prefetch" href="//code.jquery.com"> | <link rel="dns-prefetch" href="//code.jquery.com"> |
<link rel="dns-prefetch" href="//ajax.googleapis.com"> | <link rel="dns-prefetch" href="//ajax.googleapis.com"> |
<link rel="stylesheet" href="' . $labsPath . 'css/jquery-ui-1.8.12.custom.css" />'; | <link rel="stylesheet" href="' . $basePath . 'css/jquery-ui-1.8.12.custom.css" />'; |
if (isDebugServer()) { | $jqmVersion = "1.0rc1"; |
$jqmcss = $labsPath . 'css/jquery.mobile-1.0b2.css'; | if (isDebugServer()) { |
$jqjs = $labsPath . 'js/jquery-1.6.2.min.js'; | $jqmcss = $basePath . "css/jquery.mobile-$jqmVersion.css"; |
$jqmjs = $labsPath . 'js/jquery.mobile-1.0b2.js'; | $jqjs = $basePath . "js/jquery-1.6.2.min.js"; |
} | $jqmjs = $basePath . "js/jquery.mobile-$jqmVersion.js"; |
else { | } else { |
$jqmcss = "//code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.css"; | $jqmcss = "//code.jquery.com/mobile/$jqmVersion/jquery.mobile-$jqmVersion.min.css"; |
$jqjs = "//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"; | $jqjs = "//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"; |
$jqmjs = "//code.jquery.com/mobile/1.0b2/jquery.mobile-1.0b2.min.js"; | $jqmjs = "//code.jquery.com/mobile/$jqmVersion/jquery.mobile-$jqmVersion.min.js"; |
} | } |
echo '<link rel="stylesheet" href="' . $jqmcss . '" /> | echo '<link rel="stylesheet" href="' . $jqmcss . '" /> |
<script src="'.$jqjs.'"></script> | <script src="' . $jqjs . '"></script> |
<script>$(document).bind("mobileinit", function(){ | <script>$(document).bind("mobileinit", function(){ |
$.mobile.ajaxEnabled = false; | $.mobile.ajaxEnabled = false; |
}); | }); |
</script> | </script> |
<script src="'.$jqmjs.'"></script> | <script src="' . $jqmjs . '"></script> |
<script src="' . $labsPath . 'js/jquery.ui.core.min.js"></script> | <script src="' . $basePath . 'js/jquery.ui.core.min.js"></script> |
<script src="' . $labsPath . 'js/jquery.ui.position.min.js"></script> | <script src="' . $basePath . 'js/jquery.ui.position.min.js"></script> |
<script src="' . $labsPath . 'js/jquery.ui.widget.min.js"></script> | <script src="' . $basePath . 'js/jquery.ui.widget.min.js"></script> |
<script src="' . $labsPath . 'js/jquery.ui.autocomplete.min.js"></script> | <script src="' . $basePath . 'js/jquery.ui.autocomplete.min.js"></script> |
<script> | <script> |
$(function() { | $(function() { |
$( "#geolocate" ).autocomplete({ | $( "#geolocate" ).autocomplete({ |
source: "lib/autocomplete.php", | source: "lib/autocomplete.php", |
minLength: 2 | minLength: 2 |
}); | }); |
$( "#from" ).autocomplete({ | $( "#from" ).autocomplete({ |
source: "lib/autocomplete.php", | source: "lib/autocomplete.php", |
minLength: 2 | minLength: 2 |
}); | }); |
$( "#to" ).autocomplete({ | $( "#to" ).autocomplete({ |
source: "lib/autocomplete.php", | source: "lib/autocomplete.php", |
minLength: 2 | minLength: 2 |
}); | }); |
}); | }); |
</script>'; | </script>'; |
echo '<style type="text/css">'; | echo '<style type="text/css">'; |
if (strstr($_SERVER['HTTP_USER_AGENT'], 'Android')) echo '.ui-shadow,.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a,.ui-body-b,.ui-btn-up-b,.ui-btn-hover-b, | if (strstr($_SERVER['HTTP_USER_AGENT'], 'Android')) |
echo '.ui-shadow,.ui-btn-up-a,.ui-btn-hover-a,.ui-btn-down-a,.ui-body-b,.ui-btn-up-b,.ui-btn-hover-b, | |
.ui-btn-down-b,.ui-bar-c,.ui-body-c,.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c,.ui-bar-c,.ui-body-d, | .ui-btn-down-b,.ui-bar-c,.ui-body-c,.ui-btn-up-c,.ui-btn-hover-c,.ui-btn-down-c,.ui-bar-c,.ui-body-d, |
.ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d,.ui-bar-d,.ui-body-e,.ui-btn-up-e,.ui-btn-hover-e, | .ui-btn-up-d,.ui-btn-hover-d,.ui-btn-down-d,.ui-bar-d,.ui-body-e,.ui-btn-up-e,.ui-btn-hover-e, |
.ui-btn-down-e,.ui-bar-e,.ui-overlay-shadow,.ui-shadow,.ui-btn-active,.ui-body-a,.ui-bar-a { | .ui-btn-down-e,.ui-bar-e,.ui-overlay-shadow,.ui-shadow,.ui-btn-active,.ui-body-a,.ui-bar-a { |
text-shadow: none; | text-shadow: none; |
box-shadow: none; | box-shadow: none; |
-webkit-box-shadow: none; | -webkit-box-shadow: none; |
}'; | }'; |
echo '</style>'; | echo '</style>'; |
echo '<link rel="stylesheet" href="' . $labsPath . 'css/local.css.php" />'; | echo '<link rel="stylesheet" href="' . $basePath . 'css/local.css.php" />'; |
if (strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad')) { | if (isIOSDevice()){ |
echo '<meta name="apple-mobile-web-app-capable" content="yes" /> | echo '<meta name="apple-mobile-web-app-capable" content="yes" /> |
<meta name="apple-mobile-web-app-status-bar-style" content="black" /> | <meta name="apple-mobile-web-app-status-bar-style" content="black" /> |
<link rel="apple-touch-startup-image" href="startup.png" /> | <link rel="apple-touch-startup-image" href="startup.png" /> |
<link rel="apple-touch-icon" href="apple-touch-icon.png" />'; | <link rel="apple-touch-icon" href="apple-touch-icon.png" />'; |
} | } |
if ($geolocate) { | if ($geolocate) { |
echo "<script> | echo "<script> |
function success(position) { | function success(position) { |
$('#error').val('Location now detected. Please wait for data to load.'); | $('#error').val('Location now detected. Please wait for data to load.'); |
$('#geolocate').val(position.coords.latitude+','+position.coords.longitude); | $('#geolocate').val(position.coords.latitude+','+position.coords.longitude); |
$.ajax({ async: false, | $.ajax({ async: false, |
success: function(){ | success: function(){ |
location.reload(true); | location.reload(true); |
}, | }, |
url: \"include/common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); | url: \"include/common.inc.php?geolocate=yes&lat=\"+position.coords.latitude+\"&lon=\"+position.coords.longitude }); |
} | } |
function error(msg) { | function error(msg) { |
$('#error').val('Error: '+msg); | $('#error').val('Error: '+msg); |
} | } |
function geolocate() { | function geolocate() { |
if (navigator.geolocation) { | if (navigator.geolocation) { |
var options = { | var options = { |
enableHighAccuracy: true, | enableHighAccuracy: true, |
timeout: 60000, | timeout: 60000, |
maximumAge: 10000 | maximumAge: 10000 |
} | } |
navigator.geolocation.getCurrentPosition(success, error, options); | navigator.geolocation.getCurrentPosition(success, error, options); |
} | } |
} | } |
$(document).ready(function() { | $(document).ready(function() { |
$('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;}); | $('#here').click(function(event) { $('#geolocate').val(geolocate()); return false;}); |
$('#here').show(); | $('#here').show(); |
}); | }); |
"; | "; |
if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") echo "geolocate();"; | if (!isset($_SESSION['lat']) || $_SESSION['lat'] == "") |
echo "</script> "; | echo "geolocate();"; |
} | echo "</script> "; |
if (isAnalyticsOn()) echo ' | } |
if (isAnalyticsOn()) | |
echo ' | |
<script type="text/javascript">' . " | <script type="text/javascript">' . " |
var _gaq = _gaq || []; | var _gaq = _gaq || []; |
_gaq.push(['_setAccount', 'UA-22173039-1']); | _gaq.push(['_setAccount', 'UA-22173039-1']); |
_gaq.push(['_trackPageview']); | _gaq.push(['_trackPageview']); |
_gaq.push(['_trackPageLoadTime']); | _gaq.push(['_trackPageLoadTime']); |
</script>"; | </script>"; |
echo '</head> | echo '</head> |
<body> | <body> |
<div id="skip"> | <div id="skip"> |
<a href="#maincontent">Skip to content</a> | <a href="#maincontent">Skip to content</a> |
</div> | </div> |
'; | '; |
if ($opendiv) { | if ($opendiv) { |
echo '<div data-role="page"> | echo '<div data-role="page"> |
<div data-role="header" data-position="inline"> | <div data-role="header" data-position="inline"> |
<a href="' . (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "javascript:history.go(-1)") . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> | <a href="' . (isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : "javascript:history.go(-1)") . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> |
<h1>' . $pageTitle . '</h1> | <h1>' . $pageTitle . '</h1> |
<a href="' . $labsPath . '/index.php" data-icon="home" class="ui-btn-right">Home</a> | <a href="' . $basePath . '/index.php" data-icon="home" class="ui-btn-right">Home</a> |
</div><!-- /header --> | </div><!-- /header --> |
<a name="maincontent" id="maincontent"></a> | <a name="maincontent" id="maincontent"></a> |
<div data-role="content"> '; | <div data-role="content"> '; |
$overrides = getServiceOverride(); | $overrides = getServiceOverride(); |
if ($overrides['service_id']) { | if ($overrides['service_id']) { |
if ($overrides['service_id'] == "noservice") { | if ($overrides['service_id'] == "noservice") { |
echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a | echo '<div id="servicewarning">Buses are <strong>not running today</strong> due to industrial action/public holiday. See <a |
href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; | href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; |
} | } else { |
else { | echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; |
echo '<div id="servicewarning">Buses are running on an altered timetable today due to industrial action/public holiday. See <a href="http://www.action.act.gov.au">http://www.action.act.gov.au</a> for details.</div>'; | } |
} | } |
} | if ($GTFSREnabled) { |
if ($serviceAlertsEnabled) { | $serviceAlerts = getServiceAlertsAsArray("agency", "0"); |
$serviceAlerts = getServiceAlerts("network","network"); | if (isset($serviceAlerts['entity']) && sizeof($serviceAlerts['entity']) > 0) { |
foreach ($serviceAlerts['entities'] as $entity) { | foreach ($serviceAlerts['entity'] as $entity) { |
echo "<div id='servicewarning'>".date("F j, g:i a",strtotime($entity['alert']['active_period']['start']))." to ". date("F j, g:i a", strtotime($entity['alert']['active_period']['end']))."<br>Warning: {$entity['alert']['description']['translation']} | echo "<div id='servicewarning'>" . date("F j, g:i a", strtotime($entity['alert']['active_period'][0]['start'])) . " to " . date("F j, g:i a", strtotime($entity['alert']['active_period'][0]['end'])) . "{$entity['alert']['header_text']['translation'][0]['text']}<br>Warning: {$entity['alert']['description_text']['translation'][0]['text']} |
<br><a href='{$entity['alert']['url']['translation']}'>Source</a> </div>"; | <br><a href='{$entity['alert']['url']['translation'][0]['text']}'>Source</a> </div>"; |
} | } |
} | } |
} | } |
} | } |
function include_footer() | } |
{ | |
global $labsPath; | function include_footer() { |
echo '<div id="footer"><a href="' . $labsPath . 'about.php">About/Contact Us</a> <a href="' . $labsPath . 'feedback.php">Feedback/Bug Report</a> <a href="' . $labsPath . 'privacy.php">Privacy Policy</a>'; | global $basePath; |
echo '</div>'; | echo '<div id="footer"><a href="' . $basePath . 'about.php">About/Contact Us</a> <a href="' . $basePath . 'feedback.php">Feedback/Bug Report</a> <a href="' . $basePath . 'privacy.php">Privacy Policy</a>'; |
if (isAnalyticsOn()) { | echo '</div>'; |
echo "<script> (function() { | if (isAnalyticsOn()) { |
echo "<script> (function() { | |
var ga = document.createElement('script'); ga.type = | var ga = document.createElement('script'); ga.type = |
'text/javascript'; ga.async = true; | 'text/javascript'; ga.async = true; |
ga.src = ('https:' == document.location.protocol ? | ga.src = ('https:' == document.location.protocol ? |
'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; |
var s = document.getElementsByTagName('script')[0]; | var s = document.getElementsByTagName('script')[0]; |
s.parentNode.insertBefore(ga, s); | s.parentNode.insertBefore(ga, s); |
})();</script>"; | })();</script>"; |
$googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); | $googleAnalyticsImageUrl = googleAnalyticsGetImageUrl(); |
echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>'; | echo '<noscript><img src="' . $googleAnalyticsImageUrl . '" /></noscript>'; |
} | } |
echo "\n</div></div></body></html>"; | echo "\n</div></div></body></html>"; |
} | } |
function placeSettings() | |
{ | function placeSettings() { |
global $service_periods; | global $service_periods; |
$geoerror = false; | $geoerror = false; |
$geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; | $geoerror = !isset($_SESSION['lat']) || !isset($_SESSION['lat']) || $_SESSION['lat'] == "" || $_SESSION['lon'] == ""; |
echo '<div id="error">'; | echo '<div id="error">'; |
if ($geoerror) { | if ($geoerror) { |
echo 'Sorry, but your location could not currently be detected. | echo 'Sorry, but your location could not currently be detected. |
Please allow location permission, wait for your location to be detected, | Please allow location permission, wait for your location to be detected, |
or enter an address/co-ordinates in the box below.'; | or enter an address/co-ordinates in the box below.'; |
} | } |
echo '</div>'; | echo '</div>'; |
echo '<div id="settings" data-role="collapsible" data-collapsed="' . !$geoerror . '"> | echo '<div id="settings" data-role="collapsible" data-collapsed="' . !$geoerror . '"> |
<h3>Change Location...</h3> | <h3>Change Location...</h3> |
<form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post"> | <form action="' . basename($_SERVER['PHP_SELF']) . "?" . $_SERVER['QUERY_STRING'] . '" method="post"> |
<div class="ui-body"> | <div class="ui-body"> |
<div data-role="fieldcontain"> | <div data-role="fieldcontain"> |
<label for="geolocate"> Current Location: </label> | <label for="geolocate"> Current Location: </label> |
<input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a> | <input type="text" id="geolocate" name="geolocate" value="' . (isset($_SESSION['lat']) && isset($_SESSION['lon']) ? $_SESSION['lat'] . "," . $_SESSION['lon'] : "Enter co-ordinates or address here") . '"/> <a href="#" style="display:none" name="here" id="here">Here?</a> |
</div> | </div> |
<input type="submit" value="Update"/> | <input type="submit" value="Update"/> |
</div></form> | </div></form> |
</div>'; | </div>'; |
} | } |
function trackEvent($category, $action, $label = "", $value = - 1) | |
{ | function trackEvent($category, $action, $label = "", $value = - 1) { |
if (isAnalyticsOn()) { | if (isAnalyticsOn()) { |
echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>"; | echo "\n<script> _gaq.push(['_trackEvent', '$category', '$action'" . ($label != "" ? ", '$label'" : "") . ($value != - 1 ? ", $value" : "") . "]);</script>"; |
} | } |
} | } |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
$service_periods = Array( | $service_periods = Array( |
'sunday', | 'sunday', |
'saturday', | 'saturday', |
'weekday' | 'weekday' |
); | ); |
function service_period($date = "") | function service_period($date = "") { |
{ | |
if (isset($_SESSION['service_period'])) | |
if (isset($_SESSION['service_period'])) return $_SESSION['service_period']; | return $_SESSION['service_period']; |
$override = getServiceOverride($date); | $override = getServiceOverride($date); |
if ($override['service_id']){ | if ($override['service_id']) { |
return $override['service_id']; | return $override['service_id']; |
} | } |
switch (date('w',($date != "" ? $date : time()))) { | switch (date('w', ($date != "" ? $date : time()))) { |
case 0: | case 0: |
return 'sunday'; | return 'sunday'; |
case 6: | case 6: |
return 'saturday'; | return 'saturday'; |
default: | default: |
return 'weekday'; | return 'weekday'; |
} | } |
} | } |
function midnight_seconds($time = "") | |
{ | function midnight_seconds($time = "") { |
// from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html | // from http://www.perturb.org/display/Perlfunc__Seconds_Since_Midnight.html |
if ($time != "") { | if ($time != "") { |
return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); | return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); |
} | } |
if (isset($_SESSION['time'])) { | if (isset($_SESSION['time'])) { |
$time = strtotime($_SESSION['time']); | $time = strtotime($_SESSION['time']); |
return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); | return (date("G", $time) * 3600) + (date("i", $time) * 60) + date("s", $time); |
} | } |
return (date("G") * 3600) + (date("i") * 60) + date("s"); | return (date("G") * 3600) + (date("i") * 60) + date("s"); |
} | } |
function midnight_seconds_to_time($seconds) | |
{ | function midnight_seconds_to_time($seconds) { |
if ($seconds > 0) { | if ($seconds > 0) { |
$midnight = mktime(0, 0, 0, date("n") , date("j") , date("Y")); | $midnight = mktime(0, 0, 0, date("n"), date("j"), date("Y")); |
return date("h:ia", $midnight + $seconds); | return date("h:ia", $midnight + $seconds); |
} | } else { |
else { | return ""; |
return ""; | } |
} | } |
} | |
function getServiceAlerts($filter_class, $filter_id) { | if ($GTFSREnabled) { |
/* | $serviceAlertCause = Array( |
"UNKNOWN_CAUSE" => "Unknown cause", | |
also need last modified epoch of client gtfs | "OTHER_CAUSE" => "Other cause", |
"TECHNICAL_PROBLEM" => "Technical problem", | |
- add,remove,patch,inform (null) | "STRIKE" => "Strike", |
- stop | "DEMONSTRATION" => "Demonstration", |
- trip | "ACCIDENT" => "Accident", |
- network | "HOLIDAY" => "Holiday", |
"WEATHER" => "Weather", | |
"MAINTENANCE" => "Maintenance", | |
"CONSTRUCTION" => "Construction", | |
"POLICE_ACTIVITY" => "Police activity", | |
"MEDICAL_EMERGENCY" => "Medical emergency" | |
); | |
$serviceAlertEffect = Array( | |
"NO_SERVICE" => "No service", | |
"REDUCED_SERVICE" => "Reduced service", | |
"SIGNIFICANT_DELAYS" => "Significant delays", | |
"DETOUR" => "Detour", | |
"ADDITIONAL_SERVICE" => "Additional service", | |
"MODIFIED_SERVICE" => "Modified service", | |
"OTHER_EFFECT" => "Other effect", | |
"UNKNOWN_EFFECT" => "Unknown effect", | |
"STOP_MOVED" => "Stop moved"); | |
set_include_path(get_include_path() . PATH_SEPARATOR . ($basePath . "lib/Protobuf-PHP/library/DrSlump/")); | |
include_once("Protobuf.php"); | |
include_once("Protobuf/Message.php"); | |
include_once("Protobuf/Registry.php"); | |
include_once("Protobuf/Descriptor.php"); | |
include_once("Protobuf/Field.php"); | |
include_once($basePath . "lib/Protobuf-PHP/gtfs-realtime.php"); | |
include_once("Protobuf/CodecInterface.php"); | |
include_once("Protobuf/Codec/PhpArray.php"); | |
include_once("Protobuf/Codec/Binary.php"); | |
include_once("Protobuf/Codec/Binary/Writer.php"); | |
include_once("Protobuf/Codec/Json.php"); | |
function getServiceAlerts($filter_class = "", $filter_id = "") { | |
/* | |
also need last modified epoch of client gtfs | |
- add,remove,patch,inform (null) | |
- stop | |
- trip | |
- network | |
- classes (WHERE=) | - classes (WHERE=) |
- route (short_name or route_id) | - route (short_name or route_id) |
- street | - street |
- stop | - stop |
- trip | - trip |
Currently support: | Currently support: |
network inform | network inform |
trip patch: stop remove | trip patch: stop remove |
street inform: route inform, trip inform, stop inform | street inform: route inform, trip inform, stop inform |
route patch: trip remove | route patch: trip remove |
*/ | */ |
$return = Array(); | $fm = new transit_realtime\FeedMessage(); |
$return['header']['gtrtfs_version'] = "1"; | $fh = new transit_realtime\FeedHeader(); |
$return['header']['timestamp'] = time(); | $fh->setGtfsRealtimeVersion(1); |
$return['entities'] = Array(); | $fh->setTimestamp(time()); |
foreach(getCurrentAlerts() as $alert) { | $fm->setHeader($fh); |
$informedEntities = getInformedAlerts($alert['id'],$_REQUEST['filter_class'],$_REQUEST['filter_id']); | foreach (getCurrentAlerts() as $alert) { |
if (sizeof($informedEntities) >0) { | $fe = new transit_realtime\FeedEntity(); |
$entity = Array(); | $fe->setId($alert['id']); |
$entity['id'] = $alert['id']; | $fe->setIsDeleted(false); |
$entity['alert']['active_period']['start'] = $alert['start']; | $alert = new transit_realtime\Alert(); |
$entity['alert']['active_period']['end'] = $alert['end']; | $tr = new transit_realtime\TimeRange(); |
$entity['alert']['url']['translation'] = $alert['url']; | $tr->setStart($alert['start']); |
$entity['alert']['description']['translation'] = $alert['description']; | $tr->setEnd($alert['end']); |
$alert->addActivePeriod($tr); | |
foreach ($informedEntities as $informedEntity) { | $informedEntities = getInformedAlerts($alert['id'], $_REQUEST['filter_class'], $_REQUEST['filter_id']); |
$informed = Array(); | if (sizeof($informedEntities) > 0) { |
$informed[$informedEntity['informed_class']."_id"] = $informedEntity['informed_id']; | $informed = Array(); |
if ($informedEntity['informed_action'] != "") $informed["x-action"] = $informedEntity['informed_action']; | $es = new transit_realtime\EntitySelector(); |
$informed[$informedEntity['class']."_type"] = $informedEntity['type']; | if ($informedEntity['informed_class'] == "agency") { |
$entity['informed'][] = $informed; | $es->setAgencyId($informedEntity['informed_id']); |
} | } |
$return['entities'][] = $entity; | if ($informedEntity['informed_class'] == "stop") { |
} | $es->setStopId($informedEntity['informed_id']); |
} | } |
return $return; | if ($informedEntity['informed_class'] == "route") { |
} | $es->setRouteId($informedEntity['informed_id']); |
function getServiceAlertsByClass() { | } |
$return = Array(); | if ($informedEntity['informed_class'] == "trip") { |
$alerts = getServiceAlerts("",""); | $td = new transit_realtime\TripDescriptor(); |
foreach ($alerts['entities'] as $entity) { | $td->setTripId($informedEntity['informed_id']); |
foreach ($entity['informed'] as $informed) { | $es->setTrip($td); |
foreach($informed as $key => $value){ | } |
if (strpos("_id",$key) > 0) { | $alert->addInformedEntity($es); |
$parts = explode($key); | } |
$class = $parts[0]; | $alert->setCause(constant("transit_realtime\Alert\Cause::" . $alert['cause'])); |
$id = $value; | $alert->setEffect(constant("transit_realtime\Alert\Effect::" . $alert['effect'])); |
} | $tsUrl = new transit_realtime\TranslatedString(); |
} | $tUrl = new transit_realtime\TranslatedString\Translation(); |
$return[$class][$id][]['entity'] = $entity; | $tUrl->setText($alert['url']); |
$return[$class][$id][]['action'] = $informed["x-action"]; | $tUrl->setLanguage("en"); |
} | $tsUrl->addTranslation($tUrl); |
} | $alert->setUrl($tsUrl); |
$tsHeaderText = new transit_realtime\TranslatedString(); | |
$tHeaderText = new transit_realtime\TranslatedString\Translation(); | |
$tHeaderText->setText($alert['header']); | |
$tHeaderText->setLanguage("en"); | |
$tsHeaderText->addTranslation($tHeaderText); | |
$alert->setHeaderText($tsHeaderText); | |
$tsDescriptionText = new transit_realtime\TranslatedString(); | |
$tDescriptionText = new transit_realtime\TranslatedString\Translation(); | |
$tDescriptionText->setText($alert['description']); | |
$tDescriptionText->setLanguage("en"); | |
$tsDescriptionText->addTranslation($tDescriptionText); | |
$alert->setDescriptionText($tsDescriptionText); | |
$fe->setAlert($alert); | |
$fm->addEntity($fe); | |
} | |
return $fm; | |
} | |
function getServiceAlertsAsArray($filter_class = "", $filter_id = "") { | |
$codec = new DrSlump\Protobuf\Codec\PhpArray(); | |
return $codec->encode(getServiceAlerts($filter_class, $filter_id)); | |
} | |
function getServiceAlertsAsBinary($filter_class = "", $filter_id = "") { | |
$codec = new DrSlump\Protobuf\Codec\Binary(); | |
return $codec->encode(getServiceAlerts($filter_class, $filter_id)); | |
} | |
function getServiceAlertsAsJSON($filter_class = "", $filter_id = "") { | |
$codec = new DrSlump\Protobuf\Codec\Json(); | |
return $codec->encode(getServiceAlerts($filter_class, $filter_id)); | |
} | |
function getServiceAlertsByClass() { | |
$return = Array(); | |
$alerts = getServiceAlertsAsArray("", ""); | |
foreach ($alerts['entities'] as $entity) { | |
foreach ($entity['informed'] as $informed) { | |
foreach ($informed as $key => $value) { | |
if (strpos("_id", $key) > 0) { | |
$parts = explode($key); | |
$class = $parts[0]; | |
$id = $value; | |
} | |
} | |
$return[$class][$id][] = $entity; | |
} | |
} | |
} | |
function getTripUpdates($filter_class = "", $filter_id = "") { | |
$fm = new transit_realtime\FeedMessage(); | |
$fh = new transit_realtime\FeedHeader(); | |
$fh->setGtfsRealtimeVersion(1); | |
$fh->setTimestamp(time()); | |
$fm->setHeader($fh); | |
foreach (getCurrentAlerts() as $alert) { | |
$informedEntities = getInformedAlerts($alert['id'], $_REQUEST['filter_class'], $_REQUEST['filter_id']); | |
$stops = Array(); | |
$routestrips = Array(); | |
if (sizeof($informedEntities) > 0) { | |
if ($informedEntity['informed_class'] == "stop" && $informed["x-action"] == "remove") { | |
$stops[] = $informedEntity['informed_id']; | |
} | |
if (($informedEntity['informed_class'] == "route" || $informedEntity['informed_class'] == "trip") && $informed["x-action"] == "patch") { | |
$routestrips[] = Array("id" => $informedEntity['informed_id'], | |
"type" => $informedEntity['informed_class']); | |
} | |
} | |
foreach ($routestrips as $routetrip) { | |
$fe = new transit_realtime\FeedEntity(); | |
$fe->setId($alert['id'] . $routetrip['id']); | |
$fe->setIsDeleted(false); | |
$tu = new transit_realtime\TripUpdate(); | |
$td = new transit_realtime\TripDescriptor(); | |
if ($routetrip['type'] == "route") { | |
$td->setRouteId($routetrip['id']); | |
} else if ($routetrip['type'] == "trip") { | |
$td->setTripId($routetrip['id']); | |
} | |
$tu->setTrip($td); | |
foreach ($stops as $stop) { | |
$stu = new transit_realtime\TripUpdate\StopTimeUpdate(); | |
$stu->setStopId($stop); | |
$stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED); | |
$tu->addStopTimeUpdate($stu); | |
} | |
$fe->setTripUpdate($tu); | |
$fm->addEntity($fe); | |
} | |
} | |
return $fm; | |
} | |
function getTripUpdatesAsArray($filter_class = "", $filter_id = "") { | |
$codec = new DrSlump\Protobuf\Codec\PhpArray(); | |
return $codec->encode(getTripUpdates($filter_class, $filter_id)); | |
} | |
function getTripUpdatesAsBinary($filter_class = "", $filter_id = "") { | |
$codec = new DrSlump\Protobuf\Codec\Binary(); | |
return $codec->encode(getTripUpdates($filter_class, $filter_id)); | |
} | |
function getTripUpdatesAsJSON($filter_class = "", $filter_id = "") { | |
$codec = new DrSlump\Protobuf\Codec\Json(); | |
return $codec->encode(getTripUpdates($filter_class, $filter_id)); | |
} | |
} | } |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
date_default_timezone_set('Australia/ACT'); | date_default_timezone_set('Australia/ACT'); |
$debugOkay = Array( | $debugOkay = Array( |
"session", | "session", |
"json", | "json", |
"phperror", | "phperror", |
"awsotp", | "awsotp", |
//"squallotp", | //"squallotp", |
//"vanilleotp", | //"vanilleotp", |
"database", | "database", |
"other" | "other" |
); | ); |
$serviceAlertsEnabled = true; | $GTFSREnabled = true; |
$cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6"; | $cloudmadeAPIkey = "daa03470bb8740298d4b10e3f03d63e6"; |
$googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q"; | $googleMapsAPIkey = "ABQIAAAA95XYXN0cki3Yj_Sb71CFvBTPaLd08ONybQDjcH_VdYtHHLgZvRTw2INzI_m17_IoOUqH3RNNmlTk1Q"; |
$otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/'; | $otpAPIurl = 'http://localhost:8080/opentripplanner-api-webapp/'; |
if (isDebug("awsotp") || php_uname('n') == "maxious.xen.prgmr.com") { | if (isDebug("awsotp") || php_uname('n') == "maxious.xen.prgmr.com") { |
$otpAPIurl = 'http://bus-main.lambdacomplex.org:8080/opentripplanner-api-webapp/'; | $otpAPIurl = 'http://bus-main.lambdacomplex.org:8080/opentripplanner-api-webapp/'; |
} | } |
if (isDebug("dotcloudotp") || php_uname('n') == "actbus-www") { | if (isDebug("dotcloudotp") || php_uname('n') == "actbus-www") { |
$otpAPIurl = 'http://otp.actbus.dotcloud.com/opentripplanner-api-webapp/'; | $otpAPIurl = 'http://otp.actbus.dotcloud.com/opentripplanner-api-webapp/'; |
} | } |
if (isDebug("squallotp")) { | if (isDebug("squallotp")) { |
$otpAPIurl = 'http://10.0.1.108:5080/opentripplanner-api-webapp/'; | $otpAPIurl = 'http://10.0.1.108:5080/opentripplanner-api-webapp/'; |
} | } |
if (isDebug("vanilleotp")) { | if (isDebug("vanilleotp")) { |
$otpAPIurl = 'http://10.0.1.135:8080/opentripplanner-api-webapp/'; | $otpAPIurl = 'http://10.0.1.135:8080/opentripplanner-api-webapp/'; |
} | } |
if (isDebug("phperror")) error_reporting(E_ALL ^ E_NOTICE); | if (isDebug("phperror")) |
$labsPath = ""; | error_reporting(E_ALL ^ E_NOTICE); |
if (strstr($_SERVER['PHP_SELF'],"labs")) $labsPath = "../"; | $basePath = ""; |
if (strstr($_SERVER['PHP_SELF'], "labs/") | |
function isDebugServer() | || strstr($_SERVER['PHP_SELF'], "myway/") |
{ | || strstr($_SERVER['PHP_SELF'], "lib/") |
return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "vanille" || $_SERVER['SERVER_NAME'] == "10.1.0.4" || $_SERVER['SERVER_NAME'] == | || strstr($_SERVER['PHP_SELF'], "geo/") |
"localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1") ; | || strstr($_SERVER['PHP_SELF'], "include/") |
|| strstr($_SERVER['PHP_SELF'], "servicealerts/")) | |
$basePath = "../"; | |
function isDebugServer() { | |
return php_sapi_name() == "cli" || isset($_SERVER['SERVER_NAME']) && ( $_SERVER['SERVER_NAME'] == "azusa" || $_SERVER['SERVER_NAME'] == "vanille" | |
|| $_SERVER['SERVER_NAME'] == "localhost" || $_SERVER['SERVER_NAME'] == "127.0.0.1"); | |
} | } |
include_once ("common-geo.inc.php"); | include_once ("common-geo.inc.php"); |
include_once ("common-net.inc.php"); | include_once ("common-net.inc.php"); |
include_once ("common-transit.inc.php"); | include_once ("common-transit.inc.php"); |
include_once ("common-db.inc.php"); | include_once ("common-db.inc.php"); |
include_once ("common-request.inc.php"); | include_once ("common-request.inc.php"); |
include_once ("common-session.inc.php"); | include_once ("common-session.inc.php"); |
include_once ("common-auth.inc.php"); | include_once ("common-auth.inc.php"); |
include_once ("common-template.inc.php"); | include_once ("common-template.inc.php"); |
function isAnalyticsOn() { | |
function isAnalyticsOn() | $user_agent = $_SERVER['HTTP_USER_AGENT']; |
{ | return!isDebugServer() && !preg_match('/cloudkick/i', $user_agent) && !preg_match('/googlebot/i', $user_agent) && |
return !isDebugServer(); | !preg_match('/baidu/i', $user_agent); |
} | } |
function isDebug($debugReason = "other") | |
{ | function isDebug($debugReason = "other") { |
global $debugOkay; | global $debugOkay; |
return in_array($debugReason, $debugOkay, false) && isDebugServer(); | return in_array($debugReason, $debugOkay, false) && isDebugServer(); |
} | } |
function debug($msg, $debugReason = "other") | function debug($msg, $debugReason = "other") { |
{ | if (isDebug($debugReason)) |
if (isDebug($debugReason)) echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n"; | echo "\n<!-- " . date(DATE_RFC822) . "\n $msg -->\n"; |
} | } |
function isJQueryMobileDevice() | function isIOSDevice() { |
{ | return strstr($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPod') || strstr($_SERVER['HTTP_USER_AGENT'], 'iPad'); |
// http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 | } |
$user_agent = $_SERVER['HTTP_USER_AGENT']; | function isJQueryMobileDevice() { |
return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); | // http://forum.jquery.com/topic/what-is-the-best-way-to-detect-all-useragents-which-can-handle-jquery-mobile#14737000002087897 |
} | $user_agent = $_SERVER['HTTP_USER_AGENT']; |
function isFastDevice() | return preg_match('/iphone/i', $user_agent) || preg_match('/android/i', $user_agent) || preg_match('/webos/i', $user_agent) || preg_match('/ios/i', $user_agent) || preg_match('/bada/i', $user_agent) || preg_match('/maemo/i', $user_agent) || preg_match('/meego/i', $user_agent) || preg_match('/fennec/i', $user_agent) || (preg_match('/symbian/i', $user_agent) && preg_match('/s60/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/symbian/i', $user_agent) && preg_match('/platform/i', $user_agent) && $browser['majorver'] >= 3) || (preg_match('/blackberry/i', $user_agent) && $browser['majorver'] >= 5) || (preg_match('/opera mobile/i', $user_agent) && $browser['majorver'] >= 10) || (preg_match('/opera mini/i', $user_agent) && $browser['majorver'] >= 5); |
{ | } |
$ua = $_SERVER['HTTP_USER_AGENT']; | |
$fastDevices = Array( | |
"Mozilla/5.0 (X11;", | function array_flatten($a, $f = array()) { |
"Mozilla/5.0 (Windows;", | if (!$a || !is_array($a)) |
"Mozilla/5.0 (iP", | return ''; |
"Mozilla/5.0 (Linux; U; Android", | foreach ($a as $k => $v) { |
"Mozilla/4.0 (compatible; MSIE" | if (is_array($v)) |
); | $f = array_flatten($v, $f); |
$slowDevices = Array( | else |
"J2ME", | $f[$k] = $v; |
"MIDP", | } |
"Opera/", | return $f; |
"Mozilla/2.0 (compatible;", | } |
"Mozilla/3.0 (compatible;" | |
); | function remove_spaces($string) { |
return true; | return str_replace(' ', '', $string); |
} | } |
function array_flatten($a, $f = array()) | |
{ | function object2array($object) { |
if (!$a || !is_array($a)) return ''; | if (is_object($object)) { |
foreach ($a as $k => $v) { | foreach ($object as $key => $value) { |
if (is_array($v)) $f = array_flatten($v, $f); | $array[$key] = $value; |
else $f[$k] = $v; | } |
} | } else { |
return $f; | $array = $object; |
} | } |
function remove_spaces($string) | return $array; |
{ | } |
return str_replace(' ', '', $string); | |
} | function startsWith($haystack, $needle, $case = true) { |
function object2array($object) | if ($case) { |
{ | return (strcmp(substr($haystack, 0, strlen($needle)), $needle) === 0); |
if (is_object($object)) { | } |
foreach ($object as $key => $value) { | return (strcasecmp(substr($haystack, 0, strlen($needle)), $needle) === 0); |
$array[$key] = $value; | } |
} | |
} | function endsWith($haystack, $needle, $case = true) { |
else { | if ($case) { |
$array = $object; | return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); |
} | } |
return $array; | return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)), $needle) === 0); |
} | } |
function startsWith($haystack, $needle, $case = true) | |
{ | function bracketsMeanNewLine($input) { |
if ($case) { | return str_replace(")", "</small>", str_replace("(", "<br><small>", $input)); |
return (strcmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); | } |
} | |
return (strcasecmp(substr($haystack, 0, strlen($needle)) , $needle) === 0); | function sksort(&$array, $subkey = "id", $sort_ascending = false) { |
} | if (count($array)) |
$temp_array[key($array)] = array_shift($array); | |
function endsWith($haystack, $needle, $case = true) | foreach ($array as $key => $val) { |
{ | $offset = 0; |
if ($case) { | $found = false; |
return (strcmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); | foreach ($temp_array as $tmp_key => $tmp_val) { |
} | if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { |
return (strcasecmp(substr($haystack, strlen($haystack) - strlen($needle)) , $needle) === 0); | $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array( |
} | $key => $val |
function bracketsMeanNewLine($input) | ), array_slice($temp_array, $offset)); |
{ | $found = true; |
return str_replace(")", "</small>", str_replace("(", "<br><small>", $input)); | } |
} | $offset++; |
function sksort(&$array, $subkey = "id", $sort_ascending = false) | } |
{ | if (!$found) |
if (count($array)) $temp_array[key($array) ] = array_shift($array); | $temp_array = array_merge($temp_array, array( |
foreach ($array as $key => $val) { | $key => $val |
$offset = 0; | )); |
$found = false; | } |
foreach ($temp_array as $tmp_key => $tmp_val) { | if ($sort_ascending) |
if (!$found and strtolower($val[$subkey]) > strtolower($tmp_val[$subkey])) { | $array = array_reverse($temp_array); |
$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( | else |
$key => $val | $array = $temp_array; |
) , array_slice($temp_array, $offset)); | } |
$found = true; | |
} | function sktimesort(&$array, $subkey = "id", $sort_ascending = false) { |
$offset++; | if (count($array)) |
} | $temp_array[key($array)] = array_shift($array); |
if (!$found) $temp_array = array_merge($temp_array, array( | foreach ($array as $key => $val) { |
$key => $val | $offset = 0; |
)); | $found = false; |
} | foreach ($temp_array as $tmp_key => $tmp_val) { |
if ($sort_ascending) $array = array_reverse($temp_array); | if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { |
else $array = $temp_array; | $temp_array = array_merge((array) array_slice($temp_array, 0, $offset), array( |
} | $key => $val |
function sktimesort(&$array, $subkey = "id", $sort_ascending = false) | ), array_slice($temp_array, $offset)); |
{ | $found = true; |
if (count($array)) $temp_array[key($array) ] = array_shift($array); | } |
foreach ($array as $key => $val) { | $offset++; |
$offset = 0; | } |
$found = false; | if (!$found) |
foreach ($temp_array as $tmp_key => $tmp_val) { | $temp_array = array_merge($temp_array, array( |
if (!$found and strtotime($val[$subkey]) > strtotime($tmp_val[$subkey])) { | $key => $val |
$temp_array = array_merge((array)array_slice($temp_array, 0, $offset) , array( | )); |
$key => $val | } |
) , array_slice($temp_array, $offset)); | if ($sort_ascending && isset($temp_array)) |
$found = true; | $array = array_reverse($temp_array); |
} | else |
$offset++; | $array = $temp_array; |
} | } |
if (!$found) $temp_array = array_merge($temp_array, array( | |
$key => $val | function r_implode($glue, $pieces) { |
)); | foreach ($pieces as $r_pieces) { |
} | if (is_array($r_pieces)) { |
if ($sort_ascending && isset($temp_array)) $array = array_reverse($temp_array); | $retVal[] = r_implode($glue, $r_pieces); |
else $array = $temp_array; | } else { |
} | $retVal[] = $r_pieces; |
function r_implode( $glue, $pieces ) | } |
{ | } |
foreach( $pieces as $r_pieces ) | return implode($glue, $retVal); |
{ | } |
if( is_array( $r_pieces ) ) | |
{ | |
$retVal[] = r_implode( $glue, $r_pieces ); | |
} | |
else | |
{ | |
$retVal[] = $r_pieces; | |
} | |
} | |
return implode( $glue, $retVal ); | |
} | |
?> | ?> |
<?php | <?php |
function getRoute($routeID) | |
/* | |
{ | * Copyright 2010,2011 Alexander Sadleir |
global $conn; | |
$query = "Select * from routes where route_id = :routeID LIMIT 1"; | Licensed under the Apache License, Version 2.0 (the "License"); |
debug($query, "database"); | you may not use this file except in compliance with the License. |
$query = $conn -> prepare($query); | You may obtain a copy of the License at |
$query -> bindParam(":routeID", $routeID); | |
$query -> execute(); | http://www.apache.org/licenses/LICENSE-2.0 |
if (!$query) { | |
databaseError($conn -> errorInfo()); | Unless required by applicable law or agreed to in writing, software |
return Array(); | distributed under the License is distributed on an "AS IS" BASIS, |
} | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
return $query -> fetch(PDO :: FETCH_ASSOC); | See the License for the specific language governing permissions and |
} | limitations under the License. |
*/ | |
function getRouteByFullName($routeFullName) | |
function getRoute($routeID) { | |
{ | global $conn; |
global $conn; | $query = "Select * from routes where route_id = :routeID LIMIT 1"; |
$query = "Select * from routes where route_short_name||route_long_name = :routeFullName LIMIT 1"; | debug($query, "database"); |
debug($query, "database"); | $query = $conn->prepare($query); |
$query = $conn -> prepare($query); | $query->bindParam(":routeID", $routeID); |
$query -> bindParam(":routeFullName", $routeFullName); | $query->execute(); |
$query -> execute(); | if (!$query) { |
if (!$query) { | databaseError($conn->errorInfo()); |
databaseError($conn -> errorInfo()); | return Array(); |
return Array(); | } |
} | return $query->fetch(PDO :: FETCH_ASSOC); |
return $query -> fetch(PDO :: FETCH_ASSOC); | } |
} | |
function getRouteByFullName($routeFullName) { | |
function getRoutes() | global $conn; |
$query = "Select * from routes where route_short_name||route_long_name = :routeFullName LIMIT 1"; | |
{ | debug($query, "database"); |
global $conn; | $query = $conn->prepare($query); |
$query = "Select * from routes order by route_short_name;"; | $query->bindParam(":routeFullName", $routeFullName); |
debug($query, "database"); | $query->execute(); |
$query = $conn -> prepare($query); | if (!$query) { |
$query -> execute(); | databaseError($conn->errorInfo()); |
if (!$query) { | return Array(); |
databaseError($conn -> errorInfo()); | } |
return Array(); | return $query->fetch(PDO :: FETCH_ASSOC); |
} | } |
return $query -> fetchAll(); | |
} | function getRoutes() { |
function getRoutesByNumber($routeNumber = "") | global $conn; |
$query = "Select * from routes order by route_short_name;"; | |
{ | debug($query, "database"); |
global $conn; | $query = $conn->prepare($query); |
if ($routeNumber != "") { | $query->execute(); |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return $query->fetchAll(); | |
} | |
function getRoutesByNumber($routeNumber = "") { | |
global $conn; | |
if ($routeNumber != "") { | |
$query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = | $query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = |
routes.route_id join stop_times on stop_times.trip_id = trips.trip_id | routes.route_id join stop_times on stop_times.trip_id = trips.trip_id |
where route_short_name = :routeNumber OR route_short_name LIKE :routeNumber2 order by route_short_name;"; | where route_short_name = :routeNumber OR route_short_name LIKE :routeNumber2 order by route_short_name;"; |
} | } else { |
else { | |
$query = "SELECT DISTINCT route_short_name from routes order by route_short_name"; | $query = "SELECT DISTINCT route_short_name from routes order by route_short_name"; |
} | } |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
if ($routeNumber != "") { | if ($routeNumber != "") { |
$query -> bindParam(":routeNumber", $routeNumber); | $query->bindParam(":routeNumber", $routeNumber); |
$routeNumber2 = "% " . $routeNumber; | $routeNumber2 = "% " . $routeNumber; |
$query -> bindParam(":routeNumber2", $routeNumber2); | $query->bindParam(":routeNumber2", $routeNumber2); |
} | } |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getRoutesByNumberSeries($routeNumberSeries = "") | |
function getRoutesByNumberSeries($routeNumberSeries = "") { | |
{ | global $conn; |
global $conn; | if (strlen($routeNumberSeries) == 1) { |
if (strlen($routeNumberSeries) == 1) { | |
return getRoutesByNumber($routeNumberSeries); | return getRoutesByNumber($routeNumberSeries); |
} | } |
$seriesMin = substr($routeNumberSeries, 0, -1) . "0"; | $seriesMin = substr($routeNumberSeries, 0, -1) . "0"; |
$seriesMax = substr($routeNumberSeries, 0, -1) . "9"; | $seriesMax = substr($routeNumberSeries, 0, -1) . "9"; |
$query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = | $query = "Select distinct routes.route_id,routes.route_short_name,routes.route_long_name,service_id from routes join trips on trips.route_id = |
routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where to_number(route_short_name, 'FM999') between :seriesMin and :seriesMax OR route_short_name LIKE :routeNumberSeries order by route_short_name;"; | routes.route_id join stop_times on stop_times.trip_id = trips.trip_id where to_number(route_short_name, 'FM999') between :seriesMin and :seriesMax OR route_short_name LIKE :routeNumberSeries order by route_short_name;"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":seriesMin", $seriesMin); | $query->bindParam(":seriesMin", $seriesMin); |
$query -> bindParam(":seriesMax", $seriesMax); | $query->bindParam(":seriesMax", $seriesMax); |
$routeNumberSeries = "% " . substr($routeNumberSeries, 0, -1) . "%"; | $routeNumberSeries = "% " . substr($routeNumberSeries, 0, -1) . "%"; |
$query -> bindParam(":routeNumberSeries", $routeNumberSeries); | $query->bindParam(":routeNumberSeries", $routeNumberSeries); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getRouteNextTrip($routeID) | |
function getRouteNextTrip($routeID) { | |
{ | global $conn; |
global $conn; | $query = "select * from routes join trips on trips.route_id = routes.route_id |
$query = "select * from routes join trips on trips.route_id = routes.route_id | |
join stop_times on stop_times.trip_id = trips.trip_id where | join stop_times on stop_times.trip_id = trips.trip_id where |
arrival_time > :currentTime and routes.route_id = :routeID order by | arrival_time > :currentTime and routes.route_id = :routeID order by |
arrival_time limit 1"; | arrival_time limit 1"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":currentTime", current_time()); | $query->bindParam(":currentTime", current_time()); |
$query -> bindParam(":routeID", $routeID); | $query->bindParam(":routeID", $routeID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$r = $query -> fetch(PDO :: FETCH_ASSOC); | $r = $query->fetch(PDO :: FETCH_ASSOC); |
// past last trip of the day special case | // past last trip of the day special case |
if (sizeof($r) < 16) { | if (sizeof($r) < 16) { |
$query = "select * from routes join trips on trips.route_id = routes.route_id | $query = "select * from routes join trips on trips.route_id = routes.route_id |
join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID order by | join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID order by |
arrival_time DESC limit 1"; | arrival_time DESC limit 1"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":routeID", $routeID); | $query->bindParam(":routeID", $routeID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$r = $query -> fetch(PDO :: FETCH_ASSOC); | $r = $query->fetch(PDO :: FETCH_ASSOC); |
} | } |
return $r; | return $r; |
} | } |
function getTimeInterpolatedRouteAtStop($routeID, $stop_id) | |
function getTimeInterpolatedRouteAtStop($routeID, $stop_id) { | |
{ | $nextTrip = getRouteNextTrip($routeID); |
$nextTrip = getRouteNextTrip($routeID); | if ($nextTrip['trip_id']) { |
if ($nextTrip['trip_id']) { | |
foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) { | foreach (getTimeInterpolatedTrip($nextTrip['trip_id']) as $tripStop) { |
if ($tripStop['stop_id'] == $stop_id) return $tripStop; | if ($tripStop['stop_id'] == $stop_id) |
} | return $tripStop; |
} | } |
} | |
return Array(); | return Array(); |
} | } |
function getRouteTrips($routeID) | |
function getRouteTrips($routeID) { | |
{ | global $conn; |
global $conn; | $query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id |
$query = "select routes.route_id,trips.trip_id,service_id,arrival_time, stop_id, stop_sequence from routes join trips on trips.route_id = routes.route_id | |
join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID and stop_sequence = '1' order by | join stop_times on stop_times.trip_id = trips.trip_id where routes.route_id = :routeID and stop_sequence = '1' order by |
arrival_time "; | arrival_time "; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":routeID", $routeID); | $query->bindParam(":routeID", $routeID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getRoutesByDestination($destination = "", $service_period = "") | |
function getRoutesByDestination($destination = "", $service_period = "") { | |
{ | global $conn; |
global $conn; | if ($service_period == "") |
if ($service_period == "") $service_period = service_period(); | $service_period = service_period(); |
if ($destination != "") { | if ($destination != "") { |
$query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id | $query = "SELECT DISTINCT trips.route_id,route_short_name,route_long_name, service_id |
FROM stop_times join trips on trips.trip_id = | FROM stop_times join trips on trips.trip_id = |
stop_times.trip_id join routes on trips.route_id = routes.route_id | stop_times.trip_id join routes on trips.route_id = routes.route_id |
WHERE route_long_name = :destination AND service_id=:service_period order by route_short_name"; | WHERE route_long_name = :destination AND service_id=:service_period order by route_short_name"; |
} | } else { |
else { | |
$query = "SELECT DISTINCT route_long_name | $query = "SELECT DISTINCT route_long_name |
FROM stop_times join trips on trips.trip_id = | FROM stop_times join trips on trips.trip_id = |
stop_times.trip_id join routes on trips.route_id = routes.route_id | stop_times.trip_id join routes on trips.route_id = routes.route_id |
WHERE service_id= :service_period order by route_long_name"; | WHERE service_id= :service_period order by route_long_name"; |
} | } |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":service_period", $service_period); | $query->bindParam(":service_period", $service_period); |
if ($destination != "") $query -> bindParam(":destination", $destination); | if ($destination != "") |
$query -> execute(); | $query->bindParam(":destination", $destination); |
if (!$query) { | $query->execute(); |
databaseError($conn -> errorInfo()); | if (!$query) { |
return Array(); | databaseError($conn->errorInfo()); |
} | return Array(); |
return $query -> fetchAll(); | } |
} | return $query->fetchAll(); |
function getRoutesBySuburb($suburb, $service_period = "") | } |
{ | function getRoutesBySuburb($suburb, $service_period = "") { |
if ($service_period == "") $service_period = service_period(); | if ($service_period == "") |
global $conn; | $service_period = service_period(); |
$query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name | global $conn; |
$query = "SELECT DISTINCT service_id,trips.route_id,route_short_name,route_long_name | |
FROM stop_times join trips on trips.trip_id = stop_times.trip_id | FROM stop_times join trips on trips.trip_id = stop_times.trip_id |
join routes on trips.route_id = routes.route_id | join routes on trips.route_id = routes.route_id |
join stops on stops.stop_id = stop_times.stop_id | join stops on stops.stop_id = stop_times.stop_id |
WHERE zone_id LIKE ':suburb AND service_id=:service_period ORDER BY route_short_name"; | WHERE zone_id LIKE ':suburb AND service_id=:service_period ORDER BY route_short_name"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":service_period", $service_period); | $query->bindParam(":service_period", $service_period); |
$suburb = "%" . $suburb . ";%"; | $suburb = "%" . $suburb . ";%"; |
$query -> bindParam(":suburb", $suburb); | $query->bindParam(":suburb", $suburb); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) | |
function getRoutesNearby($lat, $lng, $limit = "", $distance = 500) { | |
{ | if ($service_period == "") |
if ($service_period == "") $service_period = service_period(); | $service_period = service_period(); |
if ($limit != "") $limitSQL = " LIMIT :limit "; | if ($limit != "") |
global $conn; | $limitSQL = " LIMIT :limit "; |
$query = "SELECT service_id,trips.route_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, | global $conn; |
$query = "SELECT service_id,trips.route_id,route_short_name,route_long_name,min(stops.stop_id) as stop_id, | |
min(ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE)) as distance | min(ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE)) as distance |
FROM stop_times | FROM stop_times |
join trips on trips.trip_id = stop_times.trip_id | join trips on trips.trip_id = stop_times.trip_id |
join routes on trips.route_id = routes.route_id | join routes on trips.route_id = routes.route_id |
join stops on stops.stop_id = stop_times.stop_id | join stops on stops.stop_id = stop_times.stop_id |
WHERE service_id=:service_period | WHERE service_id=:service_period |
AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE) | AND ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE) |
group by service_id,trips.route_id,route_short_name,route_long_name | group by service_id,trips.route_id,route_short_name,route_long_name |
order by distance $limitSQL"; | order by distance $limitSQL"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":service_period", $service_period); | $query->bindParam(":service_period", $service_period); |
$query -> bindParam(":distance", $distance); | $query->bindParam(":distance", $distance); |
if ($limit != "") $query -> bindParam(":limit", $limit); | if ($limit != "") |
$query -> execute(); | $query->bindParam(":limit", $limit); |
if (!$query) { | $query->execute(); |
databaseError($conn -> errorInfo()); | if (!$query) { |
return Array(); | databaseError($conn->errorInfo()); |
} | return Array(); |
return $query -> fetchAll(); | } |
} | return $query->fetchAll(); |
} | |
?> | ?> |
<?php | <?php |
function getServiceOverride($date = "") | |
{ | |
global $conn; | |
$query = "Select * from calendar_dates where date = :date and exception_type = '1' LIMIT 1"; | |
// debug($query,"database"); | |
$query = $conn -> prepare($query); // Create a prepared statement | |
$query -> bindParam(":date", date("Ymd", ($date != "" ? $date : time()))); | |
$query -> execute(); | |
if (!$query) { | |
databaseError($conn -> errorInfo()); | |
return Array(); | |
} | |
return $query -> fetch(PDO :: FETCH_ASSOC); | |
} | |
function getServiceAlert($alertID) | /* |
{ | * Copyright 2010,2011 Alexander Sadleir |
global $conn; | |
$query = 'SELECT * from servicealerts_alerts where id = :servicealert_id'; | |
debug($query, "database"); | |
$query = $conn -> prepare($query); | |
$query -> bindParam(":servicealert_id", $alertID); | |
$query -> execute(); | |
if (!$query) { | |
databaseError($conn -> errorInfo()); | |
return Array(); | |
} | |
return $query -> fetch(PDO :: FETCH_ASSOC); | |
} | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
function updateServiceAlert($alertID, $start, $end, $description, $url) | http://www.apache.org/licenses/LICENSE-2.0 |
{ | |
global $conn; | |
$query = 'update servicealerts_alerts set start=:start, "end"=:end, description=:description, url=:url where id = :servicealert_id'; | |
debug($query, "database"); | |
$query = $conn -> prepare($query); | |
$query -> bindParam(":servicealert_id", $alertID); | |
$query -> bindParam(":start", $start); | |
$query -> bindParam(":end", $end); | |
$query -> bindParam(":description", $description); | |
$query -> bindParam(":url", $url); | |
$query -> execute(); | |
print_r($conn -> errorInfo()); | Unless required by applicable law or agreed to in writing, software |
if (!$query) { | distributed under the License is distributed on an "AS IS" BASIS, |
databaseError($conn -> errorInfo()); | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
return Array(); | See the License for the specific language governing permissions and |
} | limitations under the License. |
return $query -> fetch(PDO :: FETCH_ASSOC); | */ |
} | |
function addServiceAlert($start, $end, $description, $url) | function getServiceOverride($date = "") { |
{ | global $conn; |
global $conn; | $query = "Select * from calendar_dates where date = :date and exception_type = '1' LIMIT 1"; |
$query = 'INSERT INTO servicealerts_alerts (start, "end", description, url) VALUES (:start, :end, :description, :url) '; | // debug($query,"database"); |
debug($query, "database"); | $query = $conn->prepare($query); // Create a prepared statement |
$query = $conn -> prepare($query); | $query->bindParam(":date", date("Ymd", ($date != "" ? $date : time()))); |
$query -> bindParam(":start", $start); | $query->execute(); |
$query -> bindParam(":end", $end); | if (!$query) { |
$query -> bindParam(":description", $description); | databaseError($conn->errorInfo()); |
$query -> bindParam(":url", $url); | return Array(); |
$query -> execute(); | } |
return $query->fetch(PDO :: FETCH_ASSOC); | |
} | |
print_r($conn -> errorInfo()); | function getServiceAlert($alertID) { |
if (!$query) { | global $conn; |
databaseError($conn -> errorInfo()); | $query = "SELECT id,extract('epoch' from start) as start, extract('epoch' from \"end\") as \"end\",cause,effect,header,description,url from servicealerts_alerts where id = :servicealert_id"; |
return Array(); | debug($query, "database"); |
} | $query = $conn->prepare($query); |
return $query -> fetch(PDO :: FETCH_ASSOC); | $query->bindParam(":servicealert_id", $alertID); |
} | $query->execute(); |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return $query->fetch(PDO :: FETCH_ASSOC); | |
} | |
function getCurrentAlerts() | function updateServiceAlert($alertID, $start, $end, $header, $description, $url) { |
{ | global $conn; |
global $conn; | $query = 'update servicealerts_alerts set start=:start, "end"=:end, header=:header, description=:description, url=:url where id = :servicealert_id'; |
$query = 'SELECT * from servicealerts_alerts where NOW() > start and NOW() < "end"'; | debug($query, "database"); |
// debug($query, "database"); | $query = $conn->prepare($query); |
$query = $conn -> prepare($query); | $query->bindParam(":servicealert_id", $alertID); |
$query -> execute(); | $query->bindParam(":start", $start); |
if (!$query) { | $query->bindParam(":end", $end); |
databaseError($conn -> errorInfo()); | $query->bindParam(":header", $header); |
return Array(); | $query->bindParam(":description", $description); |
} | $query->bindParam(":url", $url); |
return $query -> fetchAll(); | $query->execute(); |
} | |
function getFutureAlerts() | print_r($conn->errorInfo()); |
{ | if (!$query) { |
global $conn; | databaseError($conn->errorInfo()); |
$query = 'SELECT * from servicealerts_alerts where NOW() > start or NOW() < "end"'; | return Array(); |
// debug($query, "database"); | } |
$query = $conn -> prepare($query); | return $query->fetch(PDO :: FETCH_ASSOC); |
$query -> execute(); | } |
if (!$query) { | |
databaseError($conn -> errorInfo()); | function addServiceAlert($start, $end, $header, $description, $url) { |
return Array(); | global $conn; |
} | $query = 'INSERT INTO servicealerts_alerts (start, "end", header, description, url) VALUES (:start, :end, :header, :description, :url) '; |
return $query -> fetchAll(); | debug($query, "database"); |
} | $query = $conn->prepare($query); |
function getInformedAlerts($id, $filter_class, $filter_id) | $query->bindParam(":start", $start); |
{ | $query->bindParam(":end", $end); |
$query->bindParam(":header", $header); | |
global $conn; | $query->bindParam(":description", $description); |
$query = "SELECT * from servicealerts_informed where servicealert_id = :servicealert_id"; | $query->bindParam(":url", $url); |
$query->execute(); | |
if ($filter_class != "") { | |
print_r($conn->errorInfo()); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return $query->fetch(PDO :: FETCH_ASSOC); | |
} | |
function getCurrentAlerts() { | |
global $conn; | |
$query = "SELECT id,extract('epoch' from start) as start, extract('epoch' from \"end\") as \"end\",cause,effect,header,description,url from servicealerts_alerts where NOW() > start and NOW() < \"end\""; | |
// debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return $query->fetchAll(); | |
} | |
function getFutureAlerts() { | |
global $conn; | |
$query = "SELECT id,extract('epoch' from start) as start, extract('epoch' from \"end\") as \"end\",cause,effect,header,description,url from servicealerts_alerts where NOW() > start or NOW() < \"end\""; | |
// debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return $query->fetchAll(); | |
} | |
function getInformedAlerts($id, $filter_class, $filter_id) { | |
global $conn; | |
$query = "SELECT * from servicealerts_informed where servicealert_id = :servicealert_id"; | |
if ($filter_class != "") { | |
$query .= " AND informed_class = :informed_class "; | $query .= " AND informed_class = :informed_class "; |
} | |
} | |
if ($filter_id != "") { | if ($filter_id != "") { |
$query .= " AND informed_id = :informed_id "; | $query .= " AND informed_id = :informed_id "; |
} | |
} | |
// debug($query, "database"); | // debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
if ($filter_class != "") { | if ($filter_class != "") { |
$query -> bindParam(":informed_class", $filter_class); | $query->bindParam(":informed_class", $filter_class); |
} | } |
if ($filter_id != "") { | if ($filter_id != "") { |
$query -> bindParam(":informed_id", $filter_id); | $query->bindParam(":informed_id", $filter_id); |
} | } |
$query -> bindParam(":servicealert_id", $id); | $query->bindParam(":servicealert_id", $id); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function deleteInformedAlert($serviceAlertID, $class, $id) | |
{ | function deleteInformedAlert($serviceAlertID, $class, $id) { |
global $conn; | global $conn; |
$query = 'DELETE from servicealerts_informed where servicealert_id = :servicealert_id and informed_class = :informed_class AND informed_id = :informed_id'; | $query = 'DELETE from servicealerts_informed where servicealert_id = :servicealert_id and informed_class = :informed_class AND informed_id = :informed_id'; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":servicealert_id", $serviceAlertID); | $query->bindParam(":servicealert_id", $serviceAlertID); |
$query -> bindParam(":informed_class", $class); | $query->bindParam(":informed_class", $class); |
$query -> bindParam(":informed_id", $id); | $query->bindParam(":informed_id", $id); |
$query -> execute(); | $query->execute(); |
print_r($conn -> errorInfo()); | print_r($conn->errorInfo()); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return null; | return null; |
} | } |
function addInformedAlert($serviceAlertID, $class, $id, $action) | |
{ | |
global $conn; | |
$query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id) VALUES(:servicealert_id ,:informed_class, :informed_id)'; | |
debug($query, "database"); | |
$query = $conn -> prepare($query); | |
$query -> bindParam(":servicealert_id", $serviceAlertID); | |
$query -> bindParam(":informed_class", $class); | |
$query -> bindParam(":informed_id", $id); | |
$query -> execute(); | |
print_r($conn -> errorInfo()); | function addInformedAlert($serviceAlertID, $class, $id, $action) { |
if (!$query) { | global $conn; |
databaseError($conn -> errorInfo()); | $query = 'INSERT INTO servicealerts_informed (servicealert_id , informed_class , informed_id) VALUES(:servicealert_id ,:informed_class, :informed_id)'; |
return Array(); | debug($query, "database"); |
} | $query = $conn->prepare($query); |
$query->bindParam(":servicealert_id", $serviceAlertID); | |
$query->bindParam(":informed_class", $class); | |
$query->bindParam(":informed_id", $id); | |
$query->execute(); | |
print_r($conn->errorInfo()); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return null; | return null; |
} | |
} | |
?> | ?> |
<?php | <?php |
function getStop($stopID) | |
/* | |
{ | * Copyright 2010,2011 Alexander Sadleir |
global $conn; | |
$query = "Select * from stops where stop_id = :stopID LIMIT 1"; | Licensed under the Apache License, Version 2.0 (the "License"); |
debug($query, "database"); | you may not use this file except in compliance with the License. |
$query = $conn -> prepare($query); | You may obtain a copy of the License at |
$query -> bindParam(":stopID", $stopID); | |
$query -> execute(); | http://www.apache.org/licenses/LICENSE-2.0 |
if (!$query) { | |
databaseError($conn -> errorInfo()); | Unless required by applicable law or agreed to in writing, software |
return Array(); | distributed under the License is distributed on an "AS IS" BASIS, |
} | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
return $query -> fetch(PDO :: FETCH_ASSOC); | See the License for the specific language governing permissions and |
} | limitations under the License. |
function getStops($timingPointsOnly = false, $firstLetter = "", $startsWith = "") | */ |
{ | function getStop($stopID) { |
global $conn; | global $conn; |
$conditions = Array(); | $query = "Select * from stops where stop_id = :stopID LIMIT 1"; |
if ($timingPointsOnly) $conditions[] = "substr(stop_code,1,2) != 'Wj'"; | debug($query, "database"); |
if ($firstLetter != "") $conditions[] = "substr(stop_name,1,1) = :firstLetter"; | $query = $conn->prepare($query); |
if ($startsWith != "") $conditions[] = "stop_name like :startsWith"; | $query->bindParam(":stopID", $stopID); |
$query = "Select * from stops"; | $query->execute(); |
if (sizeof($conditions) > 0) { | if (!$query) { |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
return $query->fetch(PDO :: FETCH_ASSOC); | |
} | |
function getStops($timingPointsOnly = false, $firstLetter = "", $startsWith = "") { | |
global $conn; | |
$conditions = Array(); | |
if ($timingPointsOnly) | |
$conditions[] = "substr(stop_code,1,2) != 'Wj'"; | |
if ($firstLetter != "") | |
$conditions[] = "substr(stop_name,1,1) = :firstLetter"; | |
if ($startsWith != "") | |
$conditions[] = "stop_name like :startsWith"; | |
$query = "Select * from stops"; | |
if (sizeof($conditions) > 0) { | |
if (sizeof($conditions) > 1) { | if (sizeof($conditions) > 1) { |
$query .= " Where " . implode(" AND ", $conditions) . " "; | $query .= " Where " . implode(" AND ", $conditions) . " "; |
} | } else { |
else { | |
$query .= " Where " . $conditions[0] . " "; | $query .= " Where " . $conditions[0] . " "; |
} | } |
} | } |
$query .= " order by stop_name;"; | $query .= " order by stop_name;"; |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
if ($firstLetter != "") $query -> bindParam(":firstLetter", $firstLetter); | if ($firstLetter != "") |
$query->bindParam(":firstLetter", $firstLetter); | |
if ($startsWith != "") { | |
if ($startsWith != "") { | |
$startsWith = $startsWith . "%"; | $startsWith = $startsWith . "%"; |
$query -> bindParam(":startsWith", $startsWith); | $query->bindParam(":startsWith", $startsWith); |
} | } |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) | |
function getNearbyStops($lat, $lng, $limit = "", $distance = 1000) { | |
{ | if ($lat == null || $lng == null) |
if ($lat == null || $lng == null) return Array(); | return Array(); |
if ($limit != "") $limitSQL = " LIMIT :limit "; | if ($limit != "") |
global $conn; | $limitSQL = " LIMIT :limit "; |
$query = "Select *, ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE) as distance | global $conn; |
$query = "Select *, ST_Distance(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), FALSE) as distance | |
from stops WHERE ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE) | from stops WHERE ST_DWithin(position, ST_GeographyFromText('SRID=4326;POINT($lng $lat)'), :distance, FALSE) |
order by distance $limitSQL;"; | order by distance $limitSQL;"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":distance", $distance); | $query->bindParam(":distance", $distance); |
$query -> bindParam(":limit", $limit); | $query->bindParam(":limit", $limit); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getStopsByName($name) | |
function getStopsByName($name) { | |
{ | global $conn; |
global $conn; | $query = "Select * from stops where stop_name LIKE :name;"; |
$query = "Select * from stops where stop_name LIKE :name;"; | debug($query, "database"); |
debug($query, "database"); | $query = $conn->prepare($query); |
$query = $conn -> prepare($query); | $name = "%" . $name . ";%"; |
$name = "%" . $name . ";%"; | $query->bindParam(":name", $name); |
$query -> bindParam(":name", $name); | $query->execute(); |
$query -> execute(); | if (!$query) { |
if (!$query) { | databaseError($conn->errorInfo()); |
databaseError($conn -> errorInfo()); | return Array(); |
return Array(); | } |
} | return $query->fetchAll(); |
return $query -> fetchAll(); | } |
} | |
function getStopsBySuburb($suburb) | function getStopsBySuburb($suburb) { |
global $conn; | |
{ | $query = "Select * from stops where zone_id LIKE :suburb order by stop_name;"; |
global $conn; | debug($query, "database"); |
$query = "Select * from stops where zone_id LIKE :suburb order by stop_name;"; | $query = $conn->prepare($query); |
debug($query, "database"); | $suburb = "%" . $suburb . ";%"; |
$query = $conn -> prepare($query); | $query->bindParam(":suburb", $suburb); |
$suburb = "%" . $suburb . ";%"; | $query->execute(); |
$query -> bindParam(":suburb", $suburb); | if (!$query) { |
$query -> execute(); | databaseError($conn->errorInfo()); |
if (!$query) { | return Array(); |
databaseError($conn -> errorInfo()); | } |
return Array(); | return $query->fetchAll(); |
} | } |
return $query -> fetchAll(); | |
} | function getStopsByStopCode($stop_code, $startsWith = "") { |
function getStopsByStopCode($stop_code, $startsWith = "") | global $conn; |
$query = "Select * from stops where (stop_code = :stop_code OR stop_code LIKE :stop_code2)"; | |
{ | if ($startsWith != "") |
global $conn; | $query .= " AND stop_name like :startsWith"; |
$query = "Select * from stops where (stop_code = :stop_code OR stop_code LIKE :stop_code2)"; | |
if ($startsWith != "") $query .= " AND stop_name like :startsWith"; | debug($query, "database"); |
$query = $conn->prepare($query); | |
debug($query, "database"); | |
$query = $conn -> prepare($query); | $query->bindParam(":stop_code", $stop_code); |
$stop_code2 = $stop_code . "%"; | |
$query -> bindParam(":stop_code", $stop_code); | $query->bindParam(":stop_code2", $stop_code2); |
$stop_code2 = $stop_code . "%"; | if ($startsWith != "") { |
$query -> bindParam(":stop_code2", $stop_code2); | |
if ($startsWith != "") { | |
$startsWith = $startsWith . "%"; | $startsWith = $startsWith . "%"; |
$query -> bindParam(":startsWith", $startsWith); | $query->bindParam(":startsWith", $startsWith); |
} | } |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getStopRoutes($stopID, $service_period) | |
function getStopRoutes($stopID, $service_period) { | |
{ | if ($service_period == "") |
if ($service_period == "") $service_period = service_period(); | $service_period = service_period(); |
global $conn; | global $conn; |
$query = "SELECT distinct service_id,trips.route_id,route_short_name,route_long_name | $query = "SELECT distinct service_id,trips.route_id,route_short_name,route_long_name |
FROM stop_times join trips on trips.trip_id = | FROM stop_times join trips on trips.trip_id = |
stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = :stopID AND service_id=:service_period"; | stop_times.trip_id join routes on trips.route_id = routes.route_id WHERE stop_id = :stopID AND service_id=:service_period"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":service_period", $service_period); | $query->bindParam(":service_period", $service_period); |
$query -> bindParam(":stopID", $stopID); | $query->bindParam(":stopID", $stopID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function getStopTrips($stopID, $service_period = "", $afterTime = "", $limit = "") | |
function getStopTrips($stopID, $service_period = "", $afterTime = "", $limit = "") { | |
{ | if ($service_period == "") |
if ($service_period == "") $service_period = service_period(); | $service_period = service_period(); |
if ($limit != "") $limitSQL = " LIMIT :limit "; | if ($limit != "") |
global $conn; | $limitSQL = " LIMIT :limit "; |
if ($afterTime != "") { | global $conn; |
if ($afterTime != "") { | |
$query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name, end_times.arrival_time as end_time | $query = " SELECT stop_times.trip_id,stop_times.arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name, end_times.arrival_time as end_time |
FROM stop_times | FROM stop_times |
join trips on trips.trip_id = | join trips on trips.trip_id = |
stop_times.trip_id | stop_times.trip_id |
join routes on trips.route_id = routes.route_id , (SELECT trip_id,max(arrival_time) as arrival_time from stop_times | join routes on trips.route_id = routes.route_id , (SELECT trip_id,max(arrival_time) as arrival_time from stop_times |
WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times | WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times |
WHERE stop_times.stop_id = :stopID | WHERE stop_times.stop_id = :stopID |
AND stop_times.trip_id = end_times.trip_id | AND stop_times.trip_id = end_times.trip_id |
AND service_id=:service_period | AND service_id=:service_period |
AND end_times.arrival_time > :afterTime | AND end_times.arrival_time > :afterTime |
ORDER BY end_time $limitSQL"; | ORDER BY end_time $limitSQL"; |
} | } else { |
else { | |
$query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name | $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_sequence,service_id,trips.route_id,route_short_name,route_long_name |
FROM stop_times | FROM stop_times |
join trips on trips.trip_id = | join trips on trips.trip_id = |
stop_times.trip_id | stop_times.trip_id |
join routes on trips.route_id = routes.route_id | join routes on trips.route_id = routes.route_id |
WHERE stop_times.stop_id = :stopID | WHERE stop_times.stop_id = :stopID |
AND service_id=:service_period | AND service_id=:service_period |
ORDER BY arrival_time $limitSQL"; | ORDER BY arrival_time $limitSQL"; |
} | } |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":service_period", $service_period); | $query->bindParam(":service_period", $service_period); |
$query -> bindParam(":stopID", $stopID); | $query->bindParam(":stopID", $stopID); |
if ($limit != "") $query -> bindParam(":limit", $limit); | if ($limit != "") |
if ($afterTime != "") $query -> bindParam(":afterTime", $afterTime); | $query->bindParam(":limit", $limit); |
$query -> execute(); | if ($afterTime != "") |
if (!$query) { | $query->bindParam(":afterTime", $afterTime); |
databaseError($conn -> errorInfo()); | $query->execute(); |
return Array(); | if (!$query) { |
} | databaseError($conn->errorInfo()); |
return $query -> fetchAll(); | return Array(); |
} | } |
function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") | return $query->fetchAll(); |
} | |
{ | |
if ($service_period == "") $service_period = service_period(); | function getStopTripsWithTimes($stopID, $time = "", $service_period = "", $time_range = "", $limit = "") { |
if ($time_range == "") $time_range = (24 * 60 * 60); | if ($service_period == "") |
if ($time == "") $time = current_time(); | $service_period = service_period(); |
if ($limit == "") $limit = 10; | if ($time_range == "") |
$trips = getStopTrips($stopID, $service_period, $time); | $time_range = (24 * 60 * 60); |
$timedTrips = Array(); | if ($time == "") |
if ($trips && sizeof($trips) > 0) { | $time = current_time(); |
if ($limit == "") | |
$limit = 10; | |
$trips = getStopTrips($stopID, $service_period, $time); | |
$timedTrips = Array(); | |
if ($trips && sizeof($trips) > 0) { | |
foreach ($trips as $trip) { | foreach ($trips as $trip) { |
if ($trip['arrival_time'] != "") { | if ($trip['arrival_time'] != "") { |
if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { | if (strtotime($trip['arrival_time']) > strtotime($time) and strtotime($trip['arrival_time']) < (strtotime($time) + $time_range)) { |
$timedTrips[] = $trip; | $timedTrips[] = $trip; |
} | } |
} | } else { |
else { | |
$timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); | $timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); |
if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { | if ($timedTrip['arrival_time'] > $time and strtotime($timedTrip['arrival_time']) < (strtotime($time) + $time_range)) { |
$timedTrips[] = $timedTrip; | $timedTrips[] = $timedTrip; |
} | } |
} | } |
if (sizeof($timedTrips) > $limit) break; | if (sizeof($timedTrips) > $limit) |
} | break; |
} | |
sktimesort($timedTrips, "arrival_time", true); | sktimesort($timedTrips, "arrival_time", true); |
} | } |
return $timedTrips; | return $timedTrips; |
} | } |
?> | ?> |
<?php | <?php |
function getTrip($tripID) | |
/* | |
{ | * Copyright 2010,2011 Alexander Sadleir |
global $conn; | |
$query = "Select * from trips | Licensed under the Apache License, Version 2.0 (the "License"); |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
function getTrip($tripID) { | |
global $conn; | |
$query = "Select * from trips | |
join routes on trips.route_id = routes.route_id | join routes on trips.route_id = routes.route_id |
where trip_id = :tripID | where trip_id = :tripID |
LIMIT 1"; | LIMIT 1"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetch(PDO :: FETCH_ASSOC); | return $query->fetch(PDO :: FETCH_ASSOC); |
} | } |
function getTripShape($tripID) | |
function getTripShape($tripID) { | |
{ | global $conn; |
global $conn; | $query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.position))) as the_route |
$query = "SELECT ST_AsKML(ST_MakeLine(geometry(a.position))) as the_route | |
FROM (SELECT position, | FROM (SELECT position, |
stop_sequence, trips.trip_id | stop_sequence, trips.trip_id |
FROM stop_times | FROM stop_times |
join trips on trips.trip_id = stop_times.trip_id | join trips on trips.trip_id = stop_times.trip_id |
join stops on stops.stop_id = stop_times.stop_id | join stops on stops.stop_id = stop_times.stop_id |
WHERE trips.trip_id = :tripID ORDER BY stop_sequence) as a group by a.trip_id"; | WHERE trips.trip_id = :tripID ORDER BY stop_sequence) as a group by a.trip_id"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchColumn(0); | return $query->fetchColumn(0); |
} | } |
function getTimeInterpolatedTrip($tripID, $range = "") | |
function getTimeInterpolatedTrip($tripID, $range = "") { | |
{ | global $conn; |
global $conn; | $query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code, |
$query = "SELECT stop_times.trip_id,arrival_time,stop_times.stop_id,stop_lat,stop_lon,stop_name,stop_code, | |
stop_sequence,service_id,trips.route_id,route_short_name,route_long_name | stop_sequence,service_id,trips.route_id,route_short_name,route_long_name |
FROM stop_times | FROM stop_times |
join trips on trips.trip_id = stop_times.trip_id | join trips on trips.trip_id = stop_times.trip_id |
join routes on trips.route_id = routes.route_id | join routes on trips.route_id = routes.route_id |
join stops on stops.stop_id = stop_times.stop_id | join stops on stops.stop_id = stop_times.stop_id |
WHERE trips.trip_id = :tripID $range ORDER BY stop_sequence"; | WHERE trips.trip_id = :tripID $range ORDER BY stop_sequence"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$stopTimes = $query -> fetchAll(); | $stopTimes = $query->fetchAll(); |
$cur_timepoint = Array(); | $cur_timepoint = Array(); |
$next_timepoint = Array(); | $next_timepoint = Array(); |
$distance_between_timepoints = 0.0; | $distance_between_timepoints = 0.0; |
$distance_traveled_between_timepoints = 0.0; | $distance_traveled_between_timepoints = 0.0; |
$rv = Array(); | $rv = Array(); |
foreach ($stopTimes as $i => $stopTime) { | foreach ($stopTimes as $i => $stopTime) { |
if ($stopTime['arrival_time'] != "") { | if ($stopTime['arrival_time'] != "") { |
// is timepoint | // is timepoint |
$cur_timepoint = $stopTime; | $cur_timepoint = $stopTime; |
$distance_between_timepoints = 0.0; | $distance_between_timepoints = 0.0; |
$distance_traveled_between_timepoints = 0.0; | $distance_traveled_between_timepoints = 0.0; |
if ($i + 1 < sizeof($stopTimes)) { | if ($i + 1 < sizeof($stopTimes)) { |
$k = $i + 1; | $k = $i + 1; |
$distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); | $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); |
while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { | while ($stopTimes[$k]["arrival_time"] == "" && $k + 1 < sizeof($stopTimes)) { |
$k += 1; | $k += 1; |
// echo "k".$k; | // echo "k".$k; |
$distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); | $distance_between_timepoints += distance($stopTimes[$k - 1]["stop_lat"], $stopTimes[$k - 1]["stop_lon"], $stopTimes[$k]["stop_lat"], $stopTimes[$k]["stop_lon"]); |
} | } |
$next_timepoint = $stopTimes[$k]; | $next_timepoint = $stopTimes[$k]; |
} | |
} | |
$rv[] = $stopTime; | $rv[] = $stopTime; |
} | } else { |
else { | |
// is untimed point | // is untimed point |
// echo "i".$i; | // echo "i".$i; |
$distance_traveled_between_timepoints += distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]); | $distance_traveled_between_timepoints += distance($stopTimes[$i - 1]["stop_lat"], $stopTimes[$i - 1]["stop_lon"], $stopTimes[$i]["stop_lat"], $stopTimes[$i]["stop_lon"]); |
// echo "$distance_traveled_between_timepoints / $distance_between_timepoints<br>"; | // echo "$distance_traveled_between_timepoints / $distance_between_timepoints<br>"; |
$distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; | $distance_percent = $distance_traveled_between_timepoints / $distance_between_timepoints; |
if ($next_timepoint["arrival_time"] != "") { | if ($next_timepoint["arrival_time"] != "") { |
$total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]); | $total_time = strtotime($next_timepoint["arrival_time"]) - strtotime($cur_timepoint["arrival_time"]); |
// echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."<br>"; | // echo strtotime($next_timepoint["arrival_time"])." - ".strtotime($cur_timepoint["arrival_time"])."<br>"; |
$time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); | $time_estimate = ($distance_percent * $total_time) + strtotime($cur_timepoint["arrival_time"]); |
$stopTime["arrival_time"] = date("H:i:s", $time_estimate); | $stopTime["arrival_time"] = date("H:i:s", $time_estimate); |
} | } else { |
else { | |
$stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; | $stopTime["arrival_time"] = $cur_timepoint["arrival_time"]; |
} | } |
$rv[] = $stopTime; | $rv[] = $stopTime; |
} | |
} | |
} | |
} | |
// var_dump($rv); | // var_dump($rv); |
return $rv; | return $rv; |
} | } |
function getTripPreviousTimePoint($tripID, $stop_sequence) | |
function getTripPreviousTimePoint($tripID, $stop_sequence) { | |
{ | global $conn; |
global $conn; | $query = " SELECT trip_id,stop_id, |
$query = " SELECT trip_id,stop_id, | |
stop_sequence | stop_sequence |
FROM stop_times | FROM stop_times |
WHERE trip_id = :tripID and stop_sequence < :stop_sequence | WHERE trip_id = :tripID and stop_sequence < :stop_sequence |
and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1"; | and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence DESC LIMIT 1"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> bindParam(":stop_sequence", $stop_sequence); | $query->bindParam(":stop_sequence", $stop_sequence); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetch(PDO :: FETCH_ASSOC); | return $query->fetch(PDO :: FETCH_ASSOC); |
} | } |
function getTripNextTimePoint($tripID, $stop_sequence) | |
function getTripNextTimePoint($tripID, $stop_sequence) { | |
{ | global $conn; |
global $conn; | $query = " SELECT trip_id,stop_id, |
$query = " SELECT trip_id,stop_id, | |
stop_sequence | stop_sequence |
FROM stop_times | FROM stop_times |
WHERE trip_id = :tripID and stop_sequence > :stop_sequence | WHERE trip_id = :tripID and stop_sequence > :stop_sequence |
and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1"; | and stop_times.arrival_time IS NOT NULL ORDER BY stop_sequence LIMIT 1"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> bindParam(":stop_sequence", $stop_sequence); | $query->bindParam(":stop_sequence", $stop_sequence); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetch(PDO :: FETCH_ASSOC); | return $query->fetch(PDO :: FETCH_ASSOC); |
} | } |
function getTimeInterpolatedTripAtStop($tripID, $stop_sequence) | |
function getTimeInterpolatedTripAtStop($tripID, $stop_sequence) { | |
{ | global $conn; |
global $conn; | // limit interpolation to between nearest actual points. |
// limit interpolation to between nearest actual points. | |
$prevTimePoint = getTripPreviousTimePoint($tripID, $stop_sequence); | $prevTimePoint = getTripPreviousTimePoint($tripID, $stop_sequence); |
$nextTimePoint = getTripNextTimePoint($tripID, $stop_sequence); | $nextTimePoint = getTripNextTimePoint($tripID, $stop_sequence); |
// echo " prev {$lowestDelta['stop_sequence']} next {$nextTimePoint['stop_sequence']} "; | // echo " prev {$lowestDelta['stop_sequence']} next {$nextTimePoint['stop_sequence']} "; |
$range = ""; | $range = ""; |
if ($prevTimePoint != "") $range .= " AND stop_sequence >= '{$prevTimePoint['stop_sequence']}'"; | if ($prevTimePoint != "") |
if ($nextTimePoint != "") $range .= " AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'"; | $range .= " AND stop_sequence >= '{$prevTimePoint['stop_sequence']}'"; |
foreach (getTimeInterpolatedTrip($tripID, $range) as $tripStop) { | if ($nextTimePoint != "") |
if ($tripStop['stop_sequence'] == $stop_sequence) return $tripStop; | $range .= " AND stop_sequence <= '{$nextTimePoint['stop_sequence']}'"; |
} | foreach (getTimeInterpolatedTrip($tripID, $range) as $tripStop) { |
if ($tripStop['stop_sequence'] == $stop_sequence) | |
return $tripStop; | |
} | |
return Array(); | return Array(); |
} | } |
function getTripStartTime($tripID) | |
function getTripStartTime($tripID) { | |
{ | global $conn; |
global $conn; | $query = "Select * from stop_times |
$query = "Select * from stop_times | |
where trip_id = :tripID | where trip_id = :tripID |
AND arrival_time IS NOT NULL | AND arrival_time IS NOT NULL |
AND stop_sequence = '1'"; | AND stop_sequence = '1'"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$r = $query -> fetch(PDO :: FETCH_ASSOC); | $r = $query->fetch(PDO :: FETCH_ASSOC); |
return $r['arrival_time']; | return $r['arrival_time']; |
} | } |
function getTripEndTime($tripID) | |
function getTripEndTime($tripID) { | |
{ | global $conn; |
global $conn; | $query = "SELECT trip_id,max(arrival_time) as arrival_time from stop_times |
$query = "SELECT trip_id,max(arrival_time) as arrival_time from stop_times | |
WHERE stop_times.arrival_time IS NOT NULL and trip_id = :tripID group by trip_id"; | WHERE stop_times.arrival_time IS NOT NULL and trip_id = :tripID group by trip_id"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":tripID", $tripID); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
$r = $query -> fetch(PDO :: FETCH_ASSOC); | $r = $query->fetch(PDO :: FETCH_ASSOC); |
return $r['arrival_time']; | return $r['arrival_time']; |
} | } |
function getActiveTrips($time) | |
function getActiveTrips($time) { | |
{ | global $conn; |
global $conn; | if ($time == "") |
if ($time == "") $time = current_time(); | $time = current_time(); |
$query = "Select distinct stop_times.trip_id, start_times.arrival_time as start_time, end_times.arrival_time as end_time from stop_times, (SELECT trip_id,arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL | $query = "Select distinct stop_times.trip_id, start_times.arrival_time as start_time, end_times.arrival_time as end_time from stop_times, (SELECT trip_id,arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL |
AND stop_sequence = '1') as start_times, (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times | AND stop_sequence = '1') as start_times, (SELECT trip_id,max(arrival_time) as arrival_time from stop_times WHERE stop_times.arrival_time IS NOT NULL group by trip_id) as end_times |
WHERE start_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id AND :time > start_times.arrival_time AND :time < end_times.arrival_time"; | WHERE start_times.trip_id = end_times.trip_id AND stop_times.trip_id = end_times.trip_id AND :time > start_times.arrival_time AND :time < end_times.arrival_time"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
$query -> bindParam(":time", $time); | $query->bindParam(":time", $time); |
$query -> execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn -> errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
return $query -> fetchAll(); | return $query->fetchAll(); |
} | } |
function viaPoints($tripID, $stop_sequence = "", $timing_points_only = true) | |
function viaPoints($tripID, $stop_sequence = "", $timing_points_only = true) { | |
{ | global $conn; |
global $conn; | $query = "SELECT stops.stop_id, stop_name, arrival_time |
$query = "SELECT stops.stop_id, stop_name, arrival_time | |
FROM stop_times join stops on stops.stop_id = stop_times.stop_id | FROM stop_times join stops on stops.stop_id = stop_times.stop_id |
WHERE stop_times.trip_id = :tripID | WHERE stop_times.trip_id = :tripID |
" . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . ($timing_points_only ? "AND substr(stop_code,1,2) != 'Wj' ": ""). " ORDER BY stop_sequence"; | " . ($stop_sequence != "" ? " AND stop_sequence > :stop_sequence " : "") . ($timing_points_only ? "AND substr(stop_code,1,2) != 'Wj' " : "") . " ORDER BY stop_sequence"; |
debug($query, "database"); | debug($query, "database"); |
$query = $conn -> prepare($query); | $query = $conn->prepare($query); |
if ($stop_sequence != "") $query -> bindParam(":stop_sequence", $stop_sequence); | if ($stop_sequence != "") |
$query -> bindParam(":tripID", $tripID); | $query->bindParam(":stop_sequence", $stop_sequence); |
$query -> execute(); | $query->bindParam(":tripID", $tripID); |
if (!$query) { | $query->execute(); |
databaseError($conn -> errorInfo()); | if (!$query) { |
return Array(); | databaseError($conn->errorInfo()); |
} | return Array(); |
return $query -> fetchAll(); | } |
} | return $query->fetchAll(); |
function viaPointNames($tripid, $stop_sequence = "") | } |
{ | function viaPointNames($tripid, $stop_sequence = "") { |
$viaPointNames = Array(); | $viaPointNames = Array(); |
foreach (viaPoints($tripid, $stop_sequence) as $point) { | foreach (viaPoints($tripid, $stop_sequence) as $point) { |
$viaPointNames[] = $point['stop_name']; | $viaPointNames[] = $point['stop_name']; |
} | } |
if (sizeof($viaPointNames) > 0) { | if (sizeof($viaPointNames) > 0) { |
return r_implode(", ", $viaPointNames); | return r_implode(", ", $viaPointNames); |
} | } else { |
else { | |
return ""; | return ""; |
} | } |
} | } |
?> | ?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
include ('include/common.inc.php'); | include ('include/common.inc.php'); |
include_header("bus.lambdacomplex.org", "index", false) | include_header("bus.lambdacomplex.org", "index", false) |
?> | ?> |
<div data-role="page"> | <div data-role="page"> |
<div data-role="content"> | <div data-role="content"> |
<div id="jqm-homeheader"> | <div id="jqm-homeheader"> |
<h1>busness time</h1><br><small>Canberra Bus Timetables and Trip Planner</small> | <h1>busness time</h1><br><small>Canberra Bus Timetables and Trip Planner</small> |
</div> | </div> |
<a name="maincontent" id="maincontent"></a> | <a name="maincontent" id="maincontent"></a> |
<a href="tripPlanner.php" data-role="button" data-icon="navigation">Launch Trip Planner...</a> | <a href="tripPlanner.php" data-role="button" data-icon="navigation">Launch Trip Planner...</a> |
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b"> | <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b"> |
<li data-role="list-divider">Timetables - Stops</li> | <li data-role="list-divider">Timetables - Stops</li> |
<li><a href="stopList.php">Major (Timing Point) Stops</a></li> | <li><a href="stopList.php">Major (Timing Point) Stops</a></li> |
<li><a href="stopList.php?allstops=yes">All Stops</a></li> | <li><a href="stopList.php?allstops=yes">All Stops</a></li> |
<li><a href="stopList.php?bysuburbs=yes">Stops By Suburb</a></li> | <li><a href="stopList.php?bysuburbs=yes">Stops By Suburb</a></li> |
<li><a class="nearby" href="stopList.php?nearby=yes">Nearby Stops</a></li> | <li><a class="nearby" href="stopList.php?nearby=yes">Nearby Stops</a></li> |
</ul> | </ul> |
<ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b"> | <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b"> |
<li data-role="list-divider">Timetables - Routes</li> | <li data-role="list-divider">Timetables - Routes</li> |
<li><a href="routeList.php">Routes By Final Destination</a></li> | <li><a href="routeList.php">Routes By Final Destination</a></li> |
<li><a href="routeList.php?bynumber=yes">Routes By Number</a></li> | <li><a href="routeList.php?bynumber=yes">Routes By Number</a></li> |
<li><a href="routeList.php?bysuburbs=yes">Routes By Suburb</a></li> | <li><a href="routeList.php?bysuburbs=yes">Routes By Suburb</a></li> |
<li><a class="nearby" href="routeList.php?nearby=yes">Nearby Routes</a></li> | <li><a class="nearby" href="routeList.php?nearby=yes">Nearby Routes</a></li> |
</ul> | </ul> |
<?php | <?php |
echo ' <a href="labs/index.php" data-role="button" data-icon="beaker">Busness R&D</a>'; | echo ' <a href="labs/index.php" data-role="button" data-icon="beaker">Busness R&D</a>'; |
include_footer(true) | echo ' <a href="myway/index.php" data-role="button">MyWay Balance and Timeliness Survey Results</a>'; |
?> | include_footer(true) |
?> | |
/*! | |
* jQuery Mobile v1.0b2 | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
/*! | |
* jQuery UI Widget @VERSION | |
* | |
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
* | |
* http://docs.jquery.com/UI/Widget | |
*/ | |
(function( $, undefined ) { | |
// jQuery 1.4+ | |
if ( $.cleanData ) { | |
var _cleanData = $.cleanData; | |
$.cleanData = function( elems ) { | |
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
$( elem ).triggerHandler( "remove" ); | |
} | |
_cleanData( elems ); | |
}; | |
} else { | |
var _remove = $.fn.remove; | |
$.fn.remove = function( selector, keepData ) { | |
return this.each(function() { | |
if ( !keepData ) { | |
if ( !selector || $.filter( selector, [ this ] ).length ) { | |
$( "*", this ).add( [ this ] ).each(function() { | |
$( this ).triggerHandler( "remove" ); | |
}); | |
} | |
} | |
return _remove.call( $(this), selector, keepData ); | |
}); | |
}; | |
} | |
$.widget = function( name, base, prototype ) { | |
var namespace = name.split( "." )[ 0 ], | |
fullName; | |
name = name.split( "." )[ 1 ]; | |
fullName = namespace + "-" + name; | |
if ( !prototype ) { | |
prototype = base; | |
base = $.Widget; | |
} | |
// create selector for plugin | |
$.expr[ ":" ][ fullName ] = function( elem ) { | |
return !!$.data( elem, name ); | |
}; | |
$[ namespace ] = $[ namespace ] || {}; | |
$[ namespace ][ name ] = function( options, element ) { | |
// allow instantiation without initializing for simple inheritance | |
if ( arguments.length ) { | |
this._createWidget( options, element ); | |
} | |
}; | |
var basePrototype = new base(); | |
// we need to make the options hash a property directly on the new instance | |
// otherwise we'll modify the options hash on the prototype that we're | |
// inheriting from | |
// $.each( basePrototype, function( key, val ) { | |
// if ( $.isPlainObject(val) ) { | |
// basePrototype[ key ] = $.extend( {}, val ); | |
// } | |
// }); | |
basePrototype.options = $.extend( true, {}, basePrototype.options ); | |
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, { | |
namespace: namespace, | |
widgetName: name, | |
widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name, | |
widgetBaseClass: fullName | |
}, prototype ); | |
$.widget.bridge( name, $[ namespace ][ name ] ); | |
}; | |
$.widget.bridge = function( name, object ) { | |
$.fn[ name ] = function( options ) { | |
var isMethodCall = typeof options === "string", | |
args = Array.prototype.slice.call( arguments, 1 ), | |
returnValue = this; | |
// allow multiple hashes to be passed on init | |
options = !isMethodCall && args.length ? | |
$.extend.apply( null, [ true, options ].concat(args) ) : | |
options; | |
// prevent calls to internal methods | |
if ( isMethodCall && options.charAt( 0 ) === "_" ) { | |
return returnValue; | |
} | |
if ( isMethodCall ) { | |
this.each(function() { | |
var instance = $.data( this, name ); | |
if ( !instance ) { | |
throw "cannot call methods on " + name + " prior to initialization; " + | |
"attempted to call method '" + options + "'"; | |
} | |
if ( !$.isFunction( instance[options] ) ) { | |
throw "no such method '" + options + "' for " + name + " widget instance"; | |
} | |
var methodValue = instance[ options ].apply( instance, args ); | |
if ( methodValue !== instance && methodValue !== undefined ) { | |
returnValue = methodValue; | |
return false; | |
} | |
}); | |
} else { | |
this.each(function() { | |
var instance = $.data( this, name ); | |
if ( instance ) { | |
instance.option( options || {} )._init(); | |
} else { | |
$.data( this, name, new object( options, this ) ); | |
} | |
}); | |
} | |
return returnValue; | |
}; | |
}; | |
$.Widget = function( options, element ) { | |
// allow instantiation without initializing for simple inheritance | |
if ( arguments.length ) { | |
this._createWidget( options, element ); | |
} | |
}; | |
$.Widget.prototype = { | |
widgetName: "widget", | |
widgetEventPrefix: "", | |
options: { | |
disabled: false | |
}, | |
_createWidget: function( options, element ) { | |
// $.widget.bridge stores the plugin instance, but we do it anyway | |
// so that it's stored even before the _create function runs | |
$.data( element, this.widgetName, this ); | |
this.element = $( element ); | |
this.options = $.extend( true, {}, | |
this.options, | |
this._getCreateOptions(), | |
options ); | |
var self = this; | |
this.element.bind( "remove." + this.widgetName, function() { | |
self.destroy(); | |
}); | |
this._create(); | |
this._trigger( "create" ); | |
this._init(); | |
}, | |
_getCreateOptions: function() { | |
var options = {}; | |
if ( $.metadata ) { | |
options = $.metadata.get( element )[ this.widgetName ]; | |
} | |
return options; | |
}, | |
_create: function() {}, | |
_init: function() {}, | |
destroy: function() { | |
this.element | |
.unbind( "." + this.widgetName ) | |
.removeData( this.widgetName ); | |
this.widget() | |
.unbind( "." + this.widgetName ) | |
.removeAttr( "aria-disabled" ) | |
.removeClass( | |
this.widgetBaseClass + "-disabled " + | |
"ui-state-disabled" ); | |
}, | |
widget: function() { | |
return this.element; | |
}, | |
option: function( key, value ) { | |
var options = key; | |
if ( arguments.length === 0 ) { | |
// don't return a reference to the internal hash | |
return $.extend( {}, this.options ); | |
} | |
if (typeof key === "string" ) { | |
if ( value === undefined ) { | |
return this.options[ key ]; | |
} | |
options = {}; | |
options[ key ] = value; | |
} | |
this._setOptions( options ); | |
return this; | |
}, | |
_setOptions: function( options ) { | |
var self = this; | |
$.each( options, function( key, value ) { | |
self._setOption( key, value ); | |
}); | |
return this; | |
}, | |
_setOption: function( key, value ) { | |
this.options[ key ] = value; | |
if ( key === "disabled" ) { | |
this.widget() | |
[ value ? "addClass" : "removeClass"]( | |
this.widgetBaseClass + "-disabled" + " " + | |
"ui-state-disabled" ) | |
.attr( "aria-disabled", value ); | |
} | |
return this; | |
}, | |
enable: function() { | |
return this._setOption( "disabled", false ); | |
}, | |
disable: function() { | |
return this._setOption( "disabled", true ); | |
}, | |
_trigger: function( type, event, data ) { | |
var callback = this.options[ type ]; | |
event = $.Event( event ); | |
event.type = ( type === this.widgetEventPrefix ? | |
type : | |
this.widgetEventPrefix + type ).toLowerCase(); | |
data = data || {}; | |
// copy original event properties over to the new event | |
// this would happen if we could call $.event.fix instead of $.Event | |
// but we don't have a way to force an event to be fixed multiple times | |
if ( event.originalEvent ) { | |
for ( var i = $.event.props.length, prop; i; ) { | |
prop = $.event.props[ --i ]; | |
event[ prop ] = event.originalEvent[ prop ]; | |
} | |
} | |
this.element.trigger( event, data ); | |
return !( $.isFunction(callback) && | |
callback.call( this.element[0], event, data ) === false || | |
event.isDefaultPrevented() ); | |
} | |
}; | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : widget factory extentions for mobile | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.widget", { | |
_getCreateOptions: function() { | |
var elem = this.element, | |
options = {}; | |
$.each( this.options, function( option ) { | |
var value = elem.jqmData( option.replace( /[A-Z]/g, function( c ) { | |
return "-" + c.toLowerCase(); | |
}) | |
); | |
if ( value !== undefined ) { | |
options[ option ] = value; | |
} | |
}); | |
return options; | |
} | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : resolution and CSS media query related helpers and behavior | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
var $window = $( window ), | |
$html = $( "html" ); | |
/* $.mobile.media method: pass a CSS media type or query and get a bool return | |
note: this feature relies on actual media query support for media queries, though types will work most anywhere | |
examples: | |
$.mobile.media('screen') //>> tests for screen media type | |
$.mobile.media('screen and (min-width: 480px)') //>> tests for screen media type with window width > 480px | |
$.mobile.media('@media screen and (-webkit-min-device-pixel-ratio: 2)') //>> tests for webkit 2x pixel ratio (iPhone 4) | |
*/ | |
$.mobile.media = (function() { | |
// TODO: use window.matchMedia once at least one UA implements it | |
var cache = {}, | |
testDiv = $( "<div id='jquery-mediatest'>" ), | |
fakeBody = $( "<body>" ).append( testDiv ); | |
return function( query ) { | |
if ( !( query in cache ) ) { | |
var styleBlock = document.createElement( "style" ), | |
cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }"; | |
//must set type for IE! | |
styleBlock.type = "text/css"; | |
if ( styleBlock.styleSheet ){ | |
styleBlock.styleSheet.cssText = cssrule; | |
} else { | |
styleBlock.appendChild( document.createTextNode(cssrule) ); | |
} | |
$html.prepend( fakeBody ).prepend( styleBlock ); | |
cache[ query ] = testDiv.css( "position" ) === "absolute"; | |
fakeBody.add( styleBlock ).remove(); | |
} | |
return cache[ query ]; | |
}; | |
})(); | |
})(jQuery);/* | |
* jQuery Mobile Framework : support tests | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
(function( $, undefined ) { | |
var fakeBody = $( "<body>" ).prependTo( "html" ), | |
fbCSS = fakeBody[ 0 ].style, | |
vendors = [ "webkit", "moz", "o" ], | |
webos = "palmGetResource" in window, //only used to rule out scrollTop | |
bb = window.blackberry; //only used to rule out box shadow, as it's filled opaque on BB | |
// thx Modernizr | |
function propExists( prop ) { | |
var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ), | |
props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " ); | |
for ( var v in props ){ | |
if ( fbCSS[ v ] !== undefined ) { | |
return true; | |
} | |
} | |
} | |
// Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting ) | |
function baseTagTest() { | |
var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/", | |
base = $( "head base" ), | |
fauxEle = null, | |
href = "", | |
link, rebase; | |
if ( !base.length ) { | |
base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( "head" ); | |
} else { | |
href = base.attr( "href" ); | |
} | |
link = $( "<a href='testurl'></a>" ).prependTo( fakeBody ); | |
rebase = link[ 0 ].href; | |
base[ 0 ].href = href ? href : location.pathname; | |
if ( fauxEle ) { | |
fauxEle.remove(); | |
} | |
return rebase.indexOf( fauxBase ) === 0; | |
} | |
// non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683 | |
// allows for inclusion of IE 6+, including Windows Mobile 7 | |
$.mobile.browser = {}; | |
$.mobile.browser.ie = (function() { | |
var v = 3, | |
div = document.createElement( "div" ), | |
a = div.all || []; | |
while ( div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->", a[ 0 ] ); | |
return v > 4 ? v : !v; | |
})(); | |
$.extend( $.support, { | |
orientation: "orientation" in window, | |
touch: "ontouchend" in document, | |
cssTransitions: "WebKitTransitionEvent" in window, | |
pushState: !!history.pushState, | |
mediaquery: $.mobile.media( "only all" ), | |
cssPseudoElement: !!propExists( "content" ), | |
boxShadow: !!propExists( "boxShadow" ) && !bb, | |
scrollTop: ( "pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[ 0 ] ) && !webos, | |
dynamicBaseTag: baseTagTest(), | |
// TODO: This is a weak test. We may want to beef this up later. | |
eventCapture: "addEventListener" in document | |
}); | |
fakeBody.remove(); | |
// $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian) | |
// or that generally work better browsing in regular http for full page refreshes (Opera Mini) | |
// Note: This detection below is used as a last resort. | |
// We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible | |
var nokiaLTE7_3 = (function(){ | |
var ua = window.navigator.userAgent; | |
//The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older | |
return ua.indexOf( "Nokia" ) > -1 && | |
( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) && | |
ua.indexOf( "AppleWebKit" ) > -1 && | |
ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ ); | |
})(); | |
$.mobile.ajaxBlacklist = | |
// BlackBerry browsers, pre-webkit | |
window.blackberry && !window.WebKitPoint || | |
// Opera Mini | |
window.operamini && Object.prototype.toString.call( window.operamini ) === "[object OperaMini]" || | |
// Symbian webkits pre 7.3 | |
nokiaLTE7_3; | |
// Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices | |
// to render the stylesheets when they're referenced before this script, as we'd recommend doing. | |
// This simply reappends the CSS in place, which for some reason makes it apply | |
if ( nokiaLTE7_3 ) { | |
$(function() { | |
$( "head link[rel=stylesheet]" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" ); | |
}); | |
} | |
// For ruling out shadows via css | |
if ( !$.support.boxShadow ) { | |
$( "html" ).addClass( "ui-mobile-nosupport-boxshadow" ); | |
} | |
})( jQuery );/* | |
* jQuery Mobile Framework : "mouse" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
// This plugin is an experiment for abstracting away the touch and mouse | |
// events so that developers don't have to worry about which method of input | |
// the device their document is loaded on supports. | |
// | |
// The idea here is to allow the developer to register listeners for the | |
// basic mouse events, such as mousedown, mousemove, mouseup, and click, | |
// and the plugin will take care of registering the correct listeners | |
// behind the scenes to invoke the listener at the fastest possible time | |
// for that device, while still retaining the order of event firing in | |
// the traditional mouse environment, should multiple handlers be registered | |
// on the same element for different events. | |
// | |
// The current version exposes the following virtual events to jQuery bind methods: | |
// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" | |
(function( $, window, document, undefined ) { | |
var dataPropertyName = "virtualMouseBindings", | |
touchTargetPropertyName = "virtualTouchID", | |
virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), | |
touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), | |
activeDocHandlers = {}, | |
resetTimerID = 0, | |
startX = 0, | |
startY = 0, | |
didScroll = false, | |
clickBlockList = [], | |
blockMouseTriggers = false, | |
blockTouchTriggers = false, | |
eventCaptureSupported = $.support.eventCapture, | |
$document = $( document ), | |
nextTouchID = 1, | |
lastTouchID = 0; | |
$.vmouse = { | |
moveDistanceThreshold: 10, | |
clickDistanceThreshold: 10, | |
resetTimerDuration: 1500 | |
}; | |
function getNativeEvent( event ) { | |
while ( event && typeof event.originalEvent !== "undefined" ) { | |
event = event.originalEvent; | |
} | |
return event; | |
} | |
function createVirtualEvent( event, eventType ) { | |
var t = event.type, | |
oe, props, ne, prop, ct, touch, i, j; | |
event = $.Event(event); | |
event.type = eventType; | |
oe = event.originalEvent; | |
props = $.event.props; | |
// copy original event properties over to the new event | |
// this would happen if we could call $.event.fix instead of $.Event | |
// but we don't have a way to force an event to be fixed multiple times | |
if ( oe ) { | |
for ( i = props.length, prop; i; ) { | |
prop = props[ --i ]; | |
event[ prop ] = oe[ prop ]; | |
} | |
} | |
if ( t.search(/^touch/) !== -1 ) { | |
ne = getNativeEvent( oe ); | |
t = ne.touches; | |
ct = ne.changedTouches; | |
touch = ( t && t.length ) ? t[0] : ( (ct && ct.length) ? ct[ 0 ] : undefined ); | |
if ( touch ) { | |
for ( j = 0, len = touchEventProps.length; j < len; j++){ | |
prop = touchEventProps[ j ]; | |
event[ prop ] = touch[ prop ]; | |
} | |
} | |
} | |
return event; | |
} | |
function getVirtualBindingFlags( element ) { | |
var flags = {}, | |
b, k; | |
while ( element ) { | |
b = $.data( element, dataPropertyName ); | |
for ( k in b ) { | |
if ( b[ k ] ) { | |
flags[ k ] = flags.hasVirtualBinding = true; | |
} | |
} | |
element = element.parentNode; | |
} | |
return flags; | |
} | |
function getClosestElementWithVirtualBinding( element, eventType ) { | |
var b; | |
while ( element ) { | |
b = $.data( element, dataPropertyName ); | |
if ( b && ( !eventType || b[ eventType ] ) ) { | |
return element; | |
} | |
element = element.parentNode; | |
} | |
return null; | |
} | |
function enableTouchBindings() { | |
blockTouchTriggers = false; | |
} | |
function disableTouchBindings() { | |
blockTouchTriggers = true; | |
} | |
function enableMouseBindings() { | |
lastTouchID = 0; | |
clickBlockList.length = 0; | |
blockMouseTriggers = false; | |
// When mouse bindings are enabled, our | |
// touch bindings are disabled. | |
disableTouchBindings(); | |
} | |
function disableMouseBindings() { | |
// When mouse bindings are disabled, our | |
// touch bindings are enabled. | |
enableTouchBindings(); | |
} | |
function startResetTimer() { | |
clearResetTimer(); | |
resetTimerID = setTimeout(function(){ | |
resetTimerID = 0; | |
enableMouseBindings(); | |
}, $.vmouse.resetTimerDuration ); | |
} | |
function clearResetTimer() { | |
if ( resetTimerID ){ | |
clearTimeout( resetTimerID ); | |
resetTimerID = 0; | |
} | |
} | |
function triggerVirtualEvent( eventType, event, flags ) { | |
var defaultPrevented = false, | |
ve; | |
if ( ( flags && flags[ eventType ] ) || | |
( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { | |
ve = createVirtualEvent( event, eventType ); | |
$( event.target).trigger( ve ); | |
defaultPrevented = ve.isDefaultPrevented(); | |
} | |
return defaultPrevented; | |
} | |
function mouseEventCallback( event ) { | |
var touchID = $.data(event.target, touchTargetPropertyName); | |
if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ){ | |
triggerVirtualEvent( "v" + event.type, event ); | |
} | |
} | |
function handleTouchStart( event ) { | |
var touches = getNativeEvent( event ).touches, | |
target, flags; | |
if ( touches && touches.length === 1 ) { | |
target = event.target; | |
flags = getVirtualBindingFlags( target ); | |
if ( flags.hasVirtualBinding ) { | |
lastTouchID = nextTouchID++; | |
$.data( target, touchTargetPropertyName, lastTouchID ); | |
clearResetTimer(); | |
disableMouseBindings(); | |
didScroll = false; | |
var t = getNativeEvent( event ).touches[ 0 ]; | |
startX = t.pageX; | |
startY = t.pageY; | |
triggerVirtualEvent( "vmouseover", event, flags ); | |
triggerVirtualEvent( "vmousedown", event, flags ); | |
} | |
} | |
} | |
function handleScroll( event ) { | |
if ( blockTouchTriggers ) { | |
return; | |
} | |
if ( !didScroll ) { | |
triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); | |
} | |
didScroll = true; | |
startResetTimer(); | |
} | |
function handleTouchMove( event ) { | |
if ( blockTouchTriggers ) { | |
return; | |
} | |
var t = getNativeEvent( event ).touches[ 0 ], | |
didCancel = didScroll, | |
moveThreshold = $.vmouse.moveDistanceThreshold; | |
didScroll = didScroll || | |
( Math.abs(t.pageX - startX) > moveThreshold || | |
Math.abs(t.pageY - startY) > moveThreshold ), | |
flags = getVirtualBindingFlags( event.target ); | |
if ( didScroll && !didCancel ) { | |
triggerVirtualEvent( "vmousecancel", event, flags ); | |
} | |
triggerVirtualEvent( "vmousemove", event, flags ); | |
startResetTimer(); | |
} | |
function handleTouchEnd( event ) { | |
if ( blockTouchTriggers ) { | |
return; | |
} | |
disableTouchBindings(); | |
var flags = getVirtualBindingFlags( event.target ), | |
t; | |
triggerVirtualEvent( "vmouseup", event, flags ); | |
if ( !didScroll ) { | |
if ( triggerVirtualEvent( "vclick", event, flags ) ) { | |
// The target of the mouse events that follow the touchend | |
// event don't necessarily match the target used during the | |
// touch. This means we need to rely on coordinates for blocking | |
// any click that is generated. | |
t = getNativeEvent( event ).changedTouches[ 0 ]; | |
clickBlockList.push({ | |
touchID: lastTouchID, | |
x: t.clientX, | |
y: t.clientY | |
}); | |
// Prevent any mouse events that follow from triggering | |
// virtual event notifications. | |
blockMouseTriggers = true; | |
} | |
} | |
triggerVirtualEvent( "vmouseout", event, flags); | |
didScroll = false; | |
startResetTimer(); | |
} | |
function hasVirtualBindings( ele ) { | |
var bindings = $.data( ele, dataPropertyName ), | |
k; | |
if ( bindings ) { | |
for ( k in bindings ) { | |
if ( bindings[ k ] ) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
function dummyMouseHandler(){} | |
function getSpecialEventObject( eventType ) { | |
var realType = eventType.substr( 1 ); | |
return { | |
setup: function( data, namespace ) { | |
// If this is the first virtual mouse binding for this element, | |
// add a bindings object to its data. | |
if ( !hasVirtualBindings( this ) ) { | |
$.data( this, dataPropertyName, {}); | |
} | |
// If setup is called, we know it is the first binding for this | |
// eventType, so initialize the count for the eventType to zero. | |
var bindings = $.data( this, dataPropertyName ); | |
bindings[ eventType ] = true; | |
// If this is the first virtual mouse event for this type, | |
// register a global handler on the document. | |
activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; | |
if ( activeDocHandlers[ eventType ] === 1 ) { | |
$document.bind( realType, mouseEventCallback ); | |
} | |
// Some browsers, like Opera Mini, won't dispatch mouse/click events | |
// for elements unless they actually have handlers registered on them. | |
// To get around this, we register dummy handlers on the elements. | |
$( this ).bind( realType, dummyMouseHandler ); | |
// For now, if event capture is not supported, we rely on mouse handlers. | |
if ( eventCaptureSupported ) { | |
// If this is the first virtual mouse binding for the document, | |
// register our touchstart handler on the document. | |
activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; | |
if (activeDocHandlers[ "touchstart" ] === 1) { | |
$document.bind( "touchstart", handleTouchStart ) | |
.bind( "touchend", handleTouchEnd ) | |
// On touch platforms, touching the screen and then dragging your finger | |
// causes the window content to scroll after some distance threshold is | |
// exceeded. On these platforms, a scroll prevents a click event from being | |
// dispatched, and on some platforms, even the touchend is suppressed. To | |
// mimic the suppression of the click event, we need to watch for a scroll | |
// event. Unfortunately, some platforms like iOS don't dispatch scroll | |
// events until *AFTER* the user lifts their finger (touchend). This means | |
// we need to watch both scroll and touchmove events to figure out whether | |
// or not a scroll happenens before the touchend event is fired. | |
.bind( "touchmove", handleTouchMove ) | |
.bind( "scroll", handleScroll ); | |
} | |
} | |
}, | |
teardown: function( data, namespace ) { | |
// If this is the last virtual binding for this eventType, | |
// remove its global handler from the document. | |
--activeDocHandlers[ eventType ]; | |
if ( !activeDocHandlers[ eventType ] ) { | |
$document.unbind( realType, mouseEventCallback ); | |
} | |
if ( eventCaptureSupported ) { | |
// If this is the last virtual mouse binding in existence, | |
// remove our document touchstart listener. | |
--activeDocHandlers[ "touchstart" ]; | |
if ( !activeDocHandlers[ "touchstart" ] ) { | |
$document.unbind( "touchstart", handleTouchStart ) | |
.unbind( "touchmove", handleTouchMove ) | |
.unbind( "touchend", handleTouchEnd ) | |
.unbind( "scroll", handleScroll ); | |
} | |
} | |
var $this = $( this ), | |
bindings = $.data( this, dataPropertyName ); | |
// teardown may be called when an element was | |
// removed from the DOM. If this is the case, | |
// jQuery core may have already stripped the element | |
// of any data bindings so we need to check it before | |
// using it. | |
if ( bindings ) { | |
bindings[ eventType ] = false; | |
} | |
// Unregister the dummy event handler. | |
$this.unbind( realType, dummyMouseHandler ); | |
// If this is the last virtual mouse binding on the | |
// element, remove the binding data from the element. | |
if ( !hasVirtualBindings( this ) ) { | |
$this.removeData( dataPropertyName ); | |
} | |
} | |
}; | |
} | |
// Expose our custom events to the jQuery bind/unbind mechanism. | |
for ( var i = 0; i < virtualEventNames.length; i++ ){ | |
$.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); | |
} | |
// Add a capture click handler to block clicks. | |
// Note that we require event capture support for this so if the device | |
// doesn't support it, we punt for now and rely solely on mouse events. | |
if ( eventCaptureSupported ) { | |
document.addEventListener( "click", function( e ){ | |
var cnt = clickBlockList.length, | |
target = e.target, | |
x, y, ele, i, o, touchID; | |
if ( cnt ) { | |
x = e.clientX; | |
y = e.clientY; | |
threshold = $.vmouse.clickDistanceThreshold; | |
// The idea here is to run through the clickBlockList to see if | |
// the current click event is in the proximity of one of our | |
// vclick events that had preventDefault() called on it. If we find | |
// one, then we block the click. | |
// | |
// Why do we have to rely on proximity? | |
// | |
// Because the target of the touch event that triggered the vclick | |
// can be different from the target of the click event synthesized | |
// by the browser. The target of a mouse/click event that is syntehsized | |
// from a touch event seems to be implementation specific. For example, | |
// some browsers will fire mouse/click events for a link that is near | |
// a touch event, even though the target of the touchstart/touchend event | |
// says the user touched outside the link. Also, it seems that with most | |
// browsers, the target of the mouse/click event is not calculated until the | |
// time it is dispatched, so if you replace an element that you touched | |
// with another element, the target of the mouse/click will be the new | |
// element underneath that point. | |
// | |
// Aside from proximity, we also check to see if the target and any | |
// of its ancestors were the ones that blocked a click. This is necessary | |
// because of the strange mouse/click target calculation done in the | |
// Android 2.1 browser, where if you click on an element, and there is a | |
// mouse/click handler on one of its ancestors, the target will be the | |
// innermost child of the touched element, even if that child is no where | |
// near the point of touch. | |
ele = target; | |
while ( ele ) { | |
for ( i = 0; i < cnt; i++ ) { | |
o = clickBlockList[ i ]; | |
touchID = 0; | |
if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || | |
$.data( ele, touchTargetPropertyName ) === o.touchID ) { | |
// XXX: We may want to consider removing matches from the block list | |
// instead of waiting for the reset timer to fire. | |
e.preventDefault(); | |
e.stopPropagation(); | |
return; | |
} | |
} | |
ele = ele.parentNode; | |
} | |
} | |
}, true); | |
} | |
})( jQuery, window, document ); | |
/* | |
* jQuery Mobile Framework : events | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
// add new event shortcuts | |
$.each( ( "touchstart touchmove touchend orientationchange throttledresize " + | |
"tap taphold swipe swipeleft swiperight scrollstart scrollstop" ).split( " " ), function( i, name ) { | |
$.fn[ name ] = function( fn ) { | |
return fn ? this.bind( name, fn ) : this.trigger( name ); | |
}; | |
$.attrFn[ name ] = true; | |
}); | |
var supportTouch = $.support.touch, | |
scrollEvent = "touchmove scroll", | |
touchStartEvent = supportTouch ? "touchstart" : "mousedown", | |
touchStopEvent = supportTouch ? "touchend" : "mouseup", | |
touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; | |
function triggerCustomEvent( obj, eventType, event ) { | |
var originalType = event.type; | |
event.type = eventType; | |
$.event.handle.call( obj, event ); | |
event.type = originalType; | |
} | |
// also handles scrollstop | |
$.event.special.scrollstart = { | |
enabled: true, | |
setup: function() { | |
var thisObject = this, | |
$this = $( thisObject ), | |
scrolling, | |
timer; | |
function trigger( event, state ) { | |
scrolling = state; | |
triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event ); | |
} | |
// iPhone triggers scroll after a small delay; use touchmove instead | |
$this.bind( scrollEvent, function( event ) { | |
if ( !$.event.special.scrollstart.enabled ) { | |
return; | |
} | |
if ( !scrolling ) { | |
trigger( event, true ); | |
} | |
clearTimeout( timer ); | |
timer = setTimeout(function() { | |
trigger( event, false ); | |
}, 50 ); | |
}); | |
} | |
}; | |
// also handles taphold | |
$.event.special.tap = { | |
setup: function() { | |
var thisObject = this, | |
$this = $( thisObject ); | |
$this.bind( "vmousedown", function( event ) { | |
if ( event.which && event.which !== 1 ) { | |
return false; | |
} | |
var touching = true, | |
origTarget = event.target, | |
origEvent = event.originalEvent, | |
timer; | |
function clearTapHandlers() { | |
touching = false; | |
clearTimeout(timer); | |
$this.unbind( "vclick", clickHandler ) | |
.unbind( "vmousecancel", clearTapHandlers ); | |
} | |
function clickHandler(event) { | |
clearTapHandlers(); | |
// ONLY trigger a 'tap' event if the start target is | |
// the same as the stop target. | |
if ( origTarget == event.target ) { | |
triggerCustomEvent( thisObject, "tap", event ); | |
} | |
} | |
$this.bind( "vmousecancel", clearTapHandlers ) | |
.bind( "vclick", clickHandler ); | |
timer = setTimeout(function() { | |
if ( touching ) { | |
triggerCustomEvent( thisObject, "taphold", event ); | |
} | |
}, 750 ); | |
}); | |
} | |
}; | |
// also handles swipeleft, swiperight | |
$.event.special.swipe = { | |
scrollSupressionThreshold: 10, // More than this horizontal displacement, and we will suppress scrolling. | |
durationThreshold: 1000, // More time than this, and it isn't a swipe. | |
horizontalDistanceThreshold: 30, // Swipe horizontal displacement must be more than this. | |
verticalDistanceThreshold: 75, // Swipe vertical displacement must be less than this. | |
setup: function() { | |
var thisObject = this, | |
$this = $( thisObject ); | |
$this.bind( touchStartEvent, function( event ) { | |
var data = event.originalEvent.touches ? | |
event.originalEvent.touches[ 0 ] : event, | |
start = { | |
time: ( new Date() ).getTime(), | |
coords: [ data.pageX, data.pageY ], | |
origin: $( event.target ) | |
}, | |
stop; | |
function moveHandler( event ) { | |
if ( !start ) { | |
return; | |
} | |
var data = event.originalEvent.touches ? | |
event.originalEvent.touches[ 0 ] : event; | |
stop = { | |
time: ( new Date() ).getTime(), | |
coords: [ data.pageX, data.pageY ] | |
}; | |
// prevent scrolling | |
if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { | |
event.preventDefault(); | |
} | |
} | |
$this.bind( touchMoveEvent, moveHandler ) | |
.one( touchStopEvent, function( event ) { | |
$this.unbind( touchMoveEvent, moveHandler ); | |
if ( start && stop ) { | |
if ( stop.time - start.time < $.event.special.swipe.durationThreshold && | |
Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && | |
Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { | |
start.origin.trigger( "swipe" ) | |
.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" ); | |
} | |
} | |
start = stop = undefined; | |
}); | |
}); | |
} | |
}; | |
(function( $, window ) { | |
// "Cowboy" Ben Alman | |
var win = $( window ), | |
special_event, | |
get_orientation, | |
last_orientation; | |
$.event.special.orientationchange = special_event = { | |
setup: function() { | |
// If the event is supported natively, return false so that jQuery | |
// will bind to the event using DOM methods. | |
if ( $.support.orientation ) { | |
return false; | |
} | |
// Get the current orientation to avoid initial double-triggering. | |
last_orientation = get_orientation(); | |
// Because the orientationchange event doesn't exist, simulate the | |
// event by testing window dimensions on resize. | |
win.bind( "throttledresize", handler ); | |
}, | |
teardown: function(){ | |
// If the event is not supported natively, return false so that | |
// jQuery will unbind the event using DOM methods. | |
if ( $.support.orientation ) { | |
return false; | |
} | |
// Because the orientationchange event doesn't exist, unbind the | |
// resize event handler. | |
win.unbind( "throttledresize", handler ); | |
}, | |
add: function( handleObj ) { | |
// Save a reference to the bound event handler. | |
var old_handler = handleObj.handler; | |
handleObj.handler = function( event ) { | |
// Modify event object, adding the .orientation property. | |
event.orientation = get_orientation(); | |
// Call the originally-bound event handler and return its result. | |
return old_handler.apply( this, arguments ); | |
}; | |
} | |
}; | |
// If the event is not supported natively, this handler will be bound to | |
// the window resize event to simulate the orientationchange event. | |
function handler() { | |
// Get the current orientation. | |
var orientation = get_orientation(); | |
if ( orientation !== last_orientation ) { | |
// The orientation has changed, so trigger the orientationchange event. | |
last_orientation = orientation; | |
win.trigger( "orientationchange" ); | |
} | |
}; | |
// Get the current page orientation. This method is exposed publicly, should it | |
// be needed, as jQuery.event.special.orientationchange.orientation() | |
$.event.special.orientationchange.orientation = get_orientation = function() { | |
var elem = document.documentElement; | |
return elem && elem.clientWidth / elem.clientHeight < 1.1 ? "portrait" : "landscape"; | |
}; | |
})( jQuery, window ); | |
// throttled resize event | |
(function() { | |
$.event.special.throttledresize = { | |
setup: function() { | |
$( this ).bind( "resize", handler ); | |
}, | |
teardown: function(){ | |
$( this ).unbind( "resize", handler ); | |
} | |
}; | |
var throttle = 250, | |
handler = function() { | |
curr = ( new Date() ).getTime(); | |
diff = curr - lastCall; | |
if ( diff >= throttle ) { | |
lastCall = curr; | |
$( this ).trigger( "throttledresize" ); | |
} else { | |
if ( heldCall ) { | |
clearTimeout( heldCall ); | |
} | |
// Promise a held call will still execute | |
heldCall = setTimeout( handler, throttle - diff ); | |
} | |
}, | |
lastCall = 0, | |
heldCall, | |
curr, | |
diff; | |
})(); | |
$.each({ | |
scrollstop: "scrollstart", | |
taphold: "tap", | |
swipeleft: "swipe", | |
swiperight: "swipe" | |
}, function( event, sourceEvent ) { | |
$.event.special[ event ] = { | |
setup: function() { | |
$( this ).bind( sourceEvent, $.noop ); | |
} | |
}; | |
}); | |
})( jQuery, this ); | |
/*! | |
* jQuery hashchange event - v1.3 - 7/21/2010 | |
* http://benalman.com/projects/jquery-hashchange-plugin/ | |
* | |
* Copyright (c) 2010 "Cowboy" Ben Alman | |
* Dual licensed under the MIT and GPL licenses. | |
* http://benalman.com/about/license/ | |
*/ | |
// Script: jQuery hashchange event | |
// | |
// *Version: 1.3, Last updated: 7/21/2010* | |
// | |
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/ | |
// GitHub - http://github.com/cowboy/jquery-hashchange/ | |
// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js | |
// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped) | |
// | |
// About: License | |
// | |
// Copyright (c) 2010 "Cowboy" Ben Alman, | |
// Dual licensed under the MIT and GPL licenses. | |
// http://benalman.com/about/license/ | |
// | |
// About: Examples | |
// | |
// These working examples, complete with fully commented code, illustrate a few | |
// ways in which this plugin can be used. | |
// | |
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/ | |
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/ | |
// | |
// About: Support and Testing | |
// | |
// Information about what version or versions of jQuery this plugin has been | |
// tested with, what browsers it has been tested in, and where the unit tests | |
// reside (so you can test it yourself). | |
// | |
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2 | |
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5, | |
// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5. | |
// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/ | |
// | |
// About: Known issues | |
// | |
// While this jQuery hashchange event implementation is quite stable and | |
// robust, there are a few unfortunate browser bugs surrounding expected | |
// hashchange event-based behaviors, independent of any JavaScript | |
// window.onhashchange abstraction. See the following examples for more | |
// information: | |
// | |
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/ | |
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/ | |
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/ | |
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/ | |
// | |
// Also note that should a browser natively support the window.onhashchange | |
// event, but not report that it does, the fallback polling loop will be used. | |
// | |
// About: Release History | |
// | |
// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more | |
// "removable" for mobile-only development. Added IE6/7 document.title | |
// support. Attempted to make Iframe as hidden as possible by using | |
// techniques from http://www.paciellogroup.com/blog/?p=604. Added | |
// support for the "shortcut" format $(window).hashchange( fn ) and | |
// $(window).hashchange() like jQuery provides for built-in events. | |
// Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and | |
// lowered its default value to 50. Added <jQuery.fn.hashchange.domain> | |
// and <jQuery.fn.hashchange.src> properties plus document-domain.html | |
// file to address access denied issues when setting document.domain in | |
// IE6/7. | |
// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin | |
// from a page on another domain would cause an error in Safari 4. Also, | |
// IE6/7 Iframe is now inserted after the body (this actually works), | |
// which prevents the page from scrolling when the event is first bound. | |
// Event can also now be bound before DOM ready, but it won't be usable | |
// before then in IE6/7. | |
// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug | |
// where browser version is incorrectly reported as 8.0, despite | |
// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag. | |
// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special | |
// window.onhashchange functionality into a separate plugin for users | |
// who want just the basic event & back button support, without all the | |
// extra awesomeness that BBQ provides. This plugin will be included as | |
// part of jQuery BBQ, but also be available separately. | |
(function($,window,undefined){ | |
'$:nomunge'; // Used by YUI compressor. | |
// Reused string. | |
var str_hashchange = 'hashchange', | |
// Method / object references. | |
doc = document, | |
fake_onhashchange, | |
special = $.event.special, | |
// Does the browser support window.onhashchange? Note that IE8 running in | |
// IE7 compatibility mode reports true for 'onhashchange' in window, even | |
// though the event isn't supported, so also test document.documentMode. | |
doc_mode = doc.documentMode, | |
supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); | |
// Get location.hash (or what you'd expect location.hash to be) sans any | |
// leading #. Thanks for making this necessary, Firefox! | |
function get_fragment( url ) { | |
url = url || location.href; | |
return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' ); | |
}; | |
// Method: jQuery.fn.hashchange | |
// | |
// Bind a handler to the window.onhashchange event or trigger all bound | |
// window.onhashchange event handlers. This behavior is consistent with | |
// jQuery's built-in event handlers. | |
// | |
// Usage: | |
// | |
// > jQuery(window).hashchange( [ handler ] ); | |
// | |
// Arguments: | |
// | |
// handler - (Function) Optional handler to be bound to the hashchange | |
// event. This is a "shortcut" for the more verbose form: | |
// jQuery(window).bind( 'hashchange', handler ). If handler is omitted, | |
// all bound window.onhashchange event handlers will be triggered. This | |
// is a shortcut for the more verbose | |
// jQuery(window).trigger( 'hashchange' ). These forms are described in | |
// the <hashchange event> section. | |
// | |
// Returns: | |
// | |
// (jQuery) The initial jQuery collection of elements. | |
// Allow the "shortcut" format $(elem).hashchange( fn ) for binding and | |
// $(elem).hashchange() for triggering, like jQuery does for built-in events. | |
$.fn[ str_hashchange ] = function( fn ) { | |
return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange ); | |
}; | |
// Property: jQuery.fn.hashchange.delay | |
// | |
// The numeric interval (in milliseconds) at which the <hashchange event> | |
// polling loop executes. Defaults to 50. | |
// Property: jQuery.fn.hashchange.domain | |
// | |
// If you're setting document.domain in your JavaScript, and you want hash | |
// history to work in IE6/7, not only must this property be set, but you must | |
// also set document.domain BEFORE jQuery is loaded into the page. This | |
// property is only applicable if you are supporting IE6/7 (or IE8 operating | |
// in "IE7 compatibility" mode). | |
// | |
// In addition, the <jQuery.fn.hashchange.src> property must be set to the | |
// path of the included "document-domain.html" file, which can be renamed or | |
// modified if necessary (note that the document.domain specified must be the | |
// same in both your main JavaScript as well as in this file). | |
// | |
// Usage: | |
// | |
// jQuery.fn.hashchange.domain = document.domain; | |
// Property: jQuery.fn.hashchange.src | |
// | |
// If, for some reason, you need to specify an Iframe src file (for example, | |
// when setting document.domain as in <jQuery.fn.hashchange.domain>), you can | |
// do so using this property. Note that when using this property, history | |
// won't be recorded in IE6/7 until the Iframe src file loads. This property | |
// is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7 | |
// compatibility" mode). | |
// | |
// Usage: | |
// | |
// jQuery.fn.hashchange.src = 'path/to/file.html'; | |
$.fn[ str_hashchange ].delay = 50; | |
/* | |
$.fn[ str_hashchange ].domain = null; | |
$.fn[ str_hashchange ].src = null; | |
*/ | |
// Event: hashchange event | |
// | |
// Fired when location.hash changes. In browsers that support it, the native | |
// HTML5 window.onhashchange event is used, otherwise a polling loop is | |
// initialized, running every <jQuery.fn.hashchange.delay> milliseconds to | |
// see if the hash has changed. In IE6/7 (and IE8 operating in "IE7 | |
// compatibility" mode), a hidden Iframe is created to allow the back button | |
// and hash-based history to work. | |
// | |
// Usage as described in <jQuery.fn.hashchange>: | |
// | |
// > // Bind an event handler. | |
// > jQuery(window).hashchange( function(e) { | |
// > var hash = location.hash; | |
// > ... | |
// > }); | |
// > | |
// > // Manually trigger the event handler. | |
// > jQuery(window).hashchange(); | |
// | |
// A more verbose usage that allows for event namespacing: | |
// | |
// > // Bind an event handler. | |
// > jQuery(window).bind( 'hashchange', function(e) { | |
// > var hash = location.hash; | |
// > ... | |
// > }); | |
// > | |
// > // Manually trigger the event handler. | |
// > jQuery(window).trigger( 'hashchange' ); | |
// | |
// Additional Notes: | |
// | |
// * The polling loop and Iframe are not created until at least one handler | |
// is actually bound to the 'hashchange' event. | |
// * If you need the bound handler(s) to execute immediately, in cases where | |
// a location.hash exists on page load, via bookmark or page refresh for | |
// example, use jQuery(window).hashchange() or the more verbose | |
// jQuery(window).trigger( 'hashchange' ). | |
// * The event can be bound before DOM ready, but since it won't be usable | |
// before then in IE6/7 (due to the necessary Iframe), recommended usage is | |
// to bind it inside a DOM ready handler. | |
// Override existing $.event.special.hashchange methods (allowing this plugin | |
// to be defined after jQuery BBQ in BBQ's source code). | |
special[ str_hashchange ] = $.extend( special[ str_hashchange ], { | |
// Called only when the first 'hashchange' event is bound to window. | |
setup: function() { | |
// If window.onhashchange is supported natively, there's nothing to do.. | |
if ( supports_onhashchange ) { return false; } | |
// Otherwise, we need to create our own. And we don't want to call this | |
// until the user binds to the event, just in case they never do, since it | |
// will create a polling loop and possibly even a hidden Iframe. | |
$( fake_onhashchange.start ); | |
}, | |
// Called only when the last 'hashchange' event is unbound from window. | |
teardown: function() { | |
// If window.onhashchange is supported natively, there's nothing to do.. | |
if ( supports_onhashchange ) { return false; } | |
// Otherwise, we need to stop ours (if possible). | |
$( fake_onhashchange.stop ); | |
} | |
}); | |
// fake_onhashchange does all the work of triggering the window.onhashchange | |
// event for browsers that don't natively support it, including creating a | |
// polling loop to watch for hash changes and in IE 6/7 creating a hidden | |
// Iframe to enable back and forward. | |
fake_onhashchange = (function(){ | |
var self = {}, | |
timeout_id, | |
// Remember the initial hash so it doesn't get triggered immediately. | |
last_hash = get_fragment(), | |
fn_retval = function(val){ return val; }, | |
history_set = fn_retval, | |
history_get = fn_retval; | |
// Start the polling loop. | |
self.start = function() { | |
timeout_id || poll(); | |
}; | |
// Stop the polling loop. | |
self.stop = function() { | |
timeout_id && clearTimeout( timeout_id ); | |
timeout_id = undefined; | |
}; | |
// This polling loop checks every $.fn.hashchange.delay milliseconds to see | |
// if location.hash has changed, and triggers the 'hashchange' event on | |
// window when necessary. | |
function poll() { | |
var hash = get_fragment(), | |
history_hash = history_get( last_hash ); | |
if ( hash !== last_hash ) { | |
history_set( last_hash = hash, history_hash ); | |
$(window).trigger( str_hashchange ); | |
} else if ( history_hash !== last_hash ) { | |
location.href = location.href.replace( /#.*/, '' ) + history_hash; | |
} | |
timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay ); | |
}; | |
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv | |
// vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv | |
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv | |
$.browser.msie && !supports_onhashchange && (function(){ | |
// Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8 | |
// when running in "IE7 compatibility" mode. | |
var iframe, | |
iframe_src; | |
// When the event is bound and polling starts in IE 6/7, create a hidden | |
// Iframe for history handling. | |
self.start = function(){ | |
if ( !iframe ) { | |
iframe_src = $.fn[ str_hashchange ].src; | |
iframe_src = iframe_src && iframe_src + get_fragment(); | |
// Create hidden Iframe. Attempt to make Iframe as hidden as possible | |
// by using techniques from http://www.paciellogroup.com/blog/?p=604. | |
iframe = $('<iframe tabindex="-1" title="empty"/>').hide() | |
// When Iframe has completely loaded, initialize the history and | |
// start polling. | |
.one( 'load', function(){ | |
iframe_src || history_set( get_fragment() ); | |
poll(); | |
}) | |
// Load Iframe src if specified, otherwise nothing. | |
.attr( 'src', iframe_src || 'javascript:0' ) | |
// Append Iframe after the end of the body to prevent unnecessary | |
// initial page scrolling (yes, this works). | |
.insertAfter( 'body' )[0].contentWindow; | |
// Whenever `document.title` changes, update the Iframe's title to | |
// prettify the back/next history menu entries. Since IE sometimes | |
// errors with "Unspecified error" the very first time this is set | |
// (yes, very useful) wrap this with a try/catch block. | |
doc.onpropertychange = function(){ | |
try { | |
if ( event.propertyName === 'title' ) { | |
iframe.document.title = doc.title; | |
} | |
} catch(e) {} | |
}; | |
} | |
}; | |
// Override the "stop" method since an IE6/7 Iframe was created. Even | |
// if there are no longer any bound event handlers, the polling loop | |
// is still necessary for back/next to work at all! | |
self.stop = fn_retval; | |
// Get history by looking at the hidden Iframe's location.hash. | |
history_get = function() { | |
return get_fragment( iframe.location.href ); | |
}; | |
// Set a new history item by opening and then closing the Iframe | |
// document, *then* setting its location.hash. If document.domain has | |
// been set, update that as well. | |
history_set = function( hash, history_hash ) { | |
var iframe_doc = iframe.document, | |
domain = $.fn[ str_hashchange ].domain; | |
if ( hash !== history_hash ) { | |
// Update Iframe with any initial `document.title` that might be set. | |
iframe_doc.title = doc.title; | |
// Opening the Iframe's document after it has been closed is what | |
// actually adds a history entry. | |
iframe_doc.open(); | |
// Set document.domain for the Iframe document as well, if necessary. | |
domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' ); | |
iframe_doc.close(); | |
// Update the Iframe's hash, for great justice. | |
iframe.location.hash = hash; | |
} | |
}; | |
})(); | |
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
// ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^ | |
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
return self; | |
})(); | |
})(jQuery,this); | |
/* | |
* jQuery Mobile Framework : "page" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.page", $.mobile.widget, { | |
options: { | |
theme: "c", | |
domCache: false | |
}, | |
_create: function() { | |
var $elem = this.element, | |
o = this.options; | |
if ( this._trigger( "beforeCreate" ) === false ) { | |
return; | |
} | |
$elem.addClass( "ui-page ui-body-" + o.theme ); | |
} | |
}); | |
})( jQuery ); | |
/*! | |
* jQuery Mobile v@VERSION | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
// jQuery.mobile configurable options | |
$.extend( $.mobile, { | |
// Namespace used framework-wide for data-attrs. Default is no namespace | |
ns: "", | |
// Define the url parameter used for referencing widget-generated sub-pages. | |
// Translates to to example.html&ui-page=subpageIdentifier | |
// hash segment before &ui-page= is used to make Ajax request | |
subPageUrlKey: "ui-page", | |
// Class assigned to page currently in view, and during transitions | |
activePageClass: "ui-page-active", | |
// Class used for "active" button state, from CSS framework | |
activeBtnClass: "ui-btn-active", | |
// Automatically handle clicks and form submissions through Ajax, when same-domain | |
ajaxEnabled: true, | |
// Automatically load and show pages based on location.hash | |
hashListeningEnabled: true, | |
// Set default page transition - 'none' for no transitions | |
defaultPageTransition: "slide", | |
// Minimum scroll distance that will be remembered when returning to a page | |
minScrollBack: screen.height / 2, | |
// Set default dialog transition - 'none' for no transitions | |
defaultDialogTransition: "pop", | |
// Show loading message during Ajax requests | |
// if false, message will not appear, but loading classes will still be toggled on html el | |
loadingMessage: "loading", | |
// Error response message - appears when an Ajax page request fails | |
pageLoadErrorMessage: "Error Loading Page", | |
//automatically initialize the DOM when it's ready | |
autoInitializePage: true, | |
// Support conditions that must be met in order to proceed | |
// default enhanced qualifications are media query support OR IE 7+ | |
gradeA: function(){ | |
return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7; | |
}, | |
// TODO might be useful upstream in jquery itself ? | |
keyCode: { | |
ALT: 18, | |
BACKSPACE: 8, | |
CAPS_LOCK: 20, | |
COMMA: 188, | |
COMMAND: 91, | |
COMMAND_LEFT: 91, // COMMAND | |
COMMAND_RIGHT: 93, | |
CONTROL: 17, | |
DELETE: 46, | |
DOWN: 40, | |
END: 35, | |
ENTER: 13, | |
ESCAPE: 27, | |
HOME: 36, | |
INSERT: 45, | |
LEFT: 37, | |
MENU: 93, // COMMAND_RIGHT | |
NUMPAD_ADD: 107, | |
NUMPAD_DECIMAL: 110, | |
NUMPAD_DIVIDE: 111, | |
NUMPAD_ENTER: 108, | |
NUMPAD_MULTIPLY: 106, | |
NUMPAD_SUBTRACT: 109, | |
PAGE_DOWN: 34, | |
PAGE_UP: 33, | |
PERIOD: 190, | |
RIGHT: 39, | |
SHIFT: 16, | |
SPACE: 32, | |
TAB: 9, | |
UP: 38, | |
WINDOWS: 91 // COMMAND | |
}, | |
// Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value | |
silentScroll: function( ypos ) { | |
if ( $.type( ypos ) !== "number" ) { | |
ypos = $.mobile.defaultHomeScroll; | |
} | |
// prevent scrollstart and scrollstop events | |
$.event.special.scrollstart.enabled = false; | |
setTimeout(function() { | |
window.scrollTo( 0, ypos ); | |
$( document ).trigger( "silentscroll", { x: 0, y: ypos }); | |
}, 20 ); | |
setTimeout(function() { | |
$.event.special.scrollstart.enabled = true; | |
}, 150 ); | |
}, | |
// Take a data attribute property, prepend the namespace | |
// and then camel case the attribute string | |
nsNormalize: function( prop ) { | |
if ( !prop ) { | |
return; | |
} | |
return $.camelCase( $.mobile.ns + prop ); | |
} | |
}); | |
// Mobile version of data and removeData and hasData methods | |
// ensures all data is set and retrieved using jQuery Mobile's data namespace | |
$.fn.jqmData = function( prop, value ) { | |
return this.data( prop ? $.mobile.nsNormalize( prop ) : prop, value ); | |
}; | |
$.jqmData = function( elem, prop, value ) { | |
return $.data( elem, $.mobile.nsNormalize( prop ), value ); | |
}; | |
$.fn.jqmRemoveData = function( prop ) { | |
return this.removeData( $.mobile.nsNormalize( prop ) ); | |
}; | |
$.jqmRemoveData = function( elem, prop ) { | |
return $.removeData( elem, $.mobile.nsNormalize( prop ) ); | |
}; | |
$.jqmHasData = function( elem, prop ) { | |
return $.hasData( elem, $.mobile.nsNormalize( prop ) ); | |
}; | |
// Monkey-patching Sizzle to filter the :jqmData selector | |
var oldFind = $.find; | |
$.find = function( selector, context, ret, extra ) { | |
selector = selector.replace(/:jqmData\(([^)]*)\)/g, "[data-" + ( $.mobile.ns || "" ) + "$1]"); | |
return oldFind.call( this, selector, context, ret, extra ); | |
}; | |
$.extend( $.find, oldFind ); | |
$.find.matches = function( expr, set ) { | |
return $.find( expr, null, null, set ); | |
}; | |
$.find.matchesSelector = function( node, expr ) { | |
return $.find( expr, null, null, [ node ] ).length > 0; | |
}; | |
})( jQuery, this ); | |
/* | |
* jQuery Mobile Framework : core utilities for auto ajax navigation, base tag mgmt, | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, undefined ) { | |
//define vars for interal use | |
var $window = $( window ), | |
$html = $( 'html' ), | |
$head = $( 'head' ), | |
//url path helpers for use in relative url management | |
path = { | |
// This scary looking regular expression parses an absolute URL or its relative | |
// variants (protocol, site, document, query, and hash), into the various | |
// components (protocol, host, path, query, fragment, etc that make up the | |
// URL as well as some other commonly used sub-parts. When used with RegExp.exec() | |
// or String.match, it parses the URL into a results array that looks like this: | |
// | |
// [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content | |
// [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread | |
// [2]: http://jblas:password@mycompany.com:8080/mail/inbox | |
// [3]: http://jblas:password@mycompany.com:8080 | |
// [4]: http: | |
// [5]: jblas:password@mycompany.com:8080 | |
// [6]: jblas:password | |
// [7]: jblas | |
// [8]: password | |
// [9]: mycompany.com:8080 | |
// [10]: mycompany.com | |
// [11]: 8080 | |
// [12]: /mail/inbox | |
// [13]: /mail/ | |
// [14]: inbox | |
// [15]: ?msg=1234&type=unread | |
// [16]: #msg-content | |
// | |
urlParseRE: /^(((([^:\/#\?]+:)?(?:\/\/((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?]+)(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/, | |
//Parse a URL into a structure that allows easy access to | |
//all of the URL components by name. | |
parseUrl: function( url ) { | |
// If we're passed an object, we'll assume that it is | |
// a parsed url object and just return it back to the caller. | |
if ( $.type( url ) === "object" ) { | |
return url; | |
} | |
var u = url || "", | |
matches = path.urlParseRE.exec( url ), | |
results; | |
if ( matches ) { | |
// Create an object that allows the caller to access the sub-matches | |
// by name. Note that IE returns an empty string instead of undefined, | |
// like all other browsers do, so we normalize everything so its consistent | |
// no matter what browser we're running on. | |
results = { | |
href: matches[0] || "", | |
hrefNoHash: matches[1] || "", | |
hrefNoSearch: matches[2] || "", | |
domain: matches[3] || "", | |
protocol: matches[4] || "", | |
authority: matches[5] || "", | |
username: matches[7] || "", | |
password: matches[8] || "", | |
host: matches[9] || "", | |
hostname: matches[10] || "", | |
port: matches[11] || "", | |
pathname: matches[12] || "", | |
directory: matches[13] || "", | |
filename: matches[14] || "", | |
search: matches[15] || "", | |
hash: matches[16] || "" | |
}; | |
} | |
return results || {}; | |
}, | |
//Turn relPath into an asbolute path. absPath is | |
//an optional absolute path which describes what | |
//relPath is relative to. | |
makePathAbsolute: function( relPath, absPath ) { | |
if ( relPath && relPath.charAt( 0 ) === "/" ) { | |
return relPath; | |
} | |
relPath = relPath || ""; | |
absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : ""; | |
var absStack = absPath ? absPath.split( "/" ) : [], | |
relStack = relPath.split( "/" ); | |
for ( var i = 0; i < relStack.length; i++ ) { | |
var d = relStack[ i ]; | |
switch ( d ) { | |
case ".": | |
break; | |
case "..": | |
if ( absStack.length ) { | |
absStack.pop(); | |
} | |
break; | |
default: | |
absStack.push( d ); | |
break; | |
} | |
} | |
return "/" + absStack.join( "/" ); | |
}, | |
//Returns true if both urls have the same domain. | |
isSameDomain: function( absUrl1, absUrl2 ) { | |
return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain; | |
}, | |
//Returns true for any relative variant. | |
isRelativeUrl: function( url ) { | |
// All relative Url variants have one thing in common, no protocol. | |
return path.parseUrl( url ).protocol === ""; | |
}, | |
//Returns true for an absolute url. | |
isAbsoluteUrl: function( url ) { | |
return path.parseUrl( url ).protocol !== ""; | |
}, | |
//Turn the specified realtive URL into an absolute one. This function | |
//can handle all relative variants (protocol, site, document, query, fragment). | |
makeUrlAbsolute: function( relUrl, absUrl ) { | |
if ( !path.isRelativeUrl( relUrl ) ) { | |
return relUrl; | |
} | |
var relObj = path.parseUrl( relUrl ), | |
absObj = path.parseUrl( absUrl ), | |
protocol = relObj.protocol || absObj.protocol, | |
authority = relObj.authority || absObj.authority, | |
hasPath = relObj.pathname !== "", | |
pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ), | |
search = relObj.search || ( !hasPath && absObj.search ) || "", | |
hash = relObj.hash; | |
return protocol + "//" + authority + pathname + search + hash; | |
}, | |
//Add search (aka query) params to the specified url. | |
addSearchParams: function( url, params ) { | |
var u = path.parseUrl( url ), | |
p = ( typeof params === "object" ) ? $.param( params ) : params, | |
s = u.search || "?"; | |
return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" ); | |
}, | |
convertUrlToDataUrl: function( absUrl ) { | |
var u = path.parseUrl( absUrl ); | |
if ( path.isEmbeddedPage( u ) ) { | |
// For embedded pages, remove the dialog hash key as in getFilePath(), | |
// otherwise the Data Url won't match the id of the embedded Page. | |
return u.hash.split( dialogHashKey )[0].replace( /^#/, "" ); | |
} else if ( path.isSameDomain( u, documentBase ) ) { | |
return u.hrefNoHash.replace( documentBase.domain, "" ); | |
} | |
return absUrl; | |
}, | |
//get path from current hash, or from a file path | |
get: function( newPath ) { | |
if( newPath === undefined ) { | |
newPath = location.hash; | |
} | |
return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' ); | |
}, | |
//return the substring of a filepath before the sub-page key, for making a server request | |
getFilePath: function( path ) { | |
var splitkey = '&' + $.mobile.subPageUrlKey; | |
return path && path.split( splitkey )[0].split( dialogHashKey )[0]; | |
}, | |
//set location hash to path | |
set: function( path ) { | |
location.hash = path; | |
}, | |
//test if a given url (string) is a path | |
//NOTE might be exceptionally naive | |
isPath: function( url ) { | |
return ( /\// ).test( url ); | |
}, | |
//return a url path with the window's location protocol/hostname/pathname removed | |
clean: function( url ) { | |
return url.replace( documentBase.domain, "" ); | |
}, | |
//just return the url without an initial # | |
stripHash: function( url ) { | |
return url.replace( /^#/, "" ); | |
}, | |
//remove the preceding hash, any query params, and dialog notations | |
cleanHash: function( hash ) { | |
return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) ); | |
}, | |
//check whether a url is referencing the same domain, or an external domain or different protocol | |
//could be mailto, etc | |
isExternal: function( url ) { | |
var u = path.parseUrl( url ); | |
return u.protocol && u.domain !== documentUrl.domain ? true : false; | |
}, | |
hasProtocol: function( url ) { | |
return ( /^(:?\w+:)/ ).test( url ); | |
}, | |
isEmbeddedPage: function( url ) { | |
var u = path.parseUrl( url ); | |
//if the path is absolute, then we need to compare the url against | |
//both the documentUrl and the documentBase. The main reason for this | |
//is that links embedded within external documents will refer to the | |
//application document, whereas links embedded within the application | |
//document will be resolved against the document base. | |
if ( u.protocol !== "" ) { | |
return ( u.hash && ( u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ) ) ); | |
} | |
return (/^#/).test( u.href ); | |
} | |
}, | |
//will be defined when a link is clicked and given an active class | |
$activeClickedLink = null, | |
//urlHistory is purely here to make guesses at whether the back or forward button was clicked | |
//and provide an appropriate transition | |
urlHistory = { | |
// Array of pages that are visited during a single page load. | |
// Each has a url and optional transition, title, and pageUrl (which represents the file path, in cases where URL is obscured, such as dialogs) | |
stack: [], | |
//maintain an index number for the active page in the stack | |
activeIndex: 0, | |
//get active | |
getActive: function() { | |
return urlHistory.stack[ urlHistory.activeIndex ]; | |
}, | |
getPrev: function() { | |
return urlHistory.stack[ urlHistory.activeIndex - 1 ]; | |
}, | |
getNext: function() { | |
return urlHistory.stack[ urlHistory.activeIndex + 1 ]; | |
}, | |
// addNew is used whenever a new page is added | |
addNew: function( url, transition, title, pageUrl ) { | |
//if there's forward history, wipe it | |
if( urlHistory.getNext() ) { | |
urlHistory.clearForward(); | |
} | |
urlHistory.stack.push( {url : url, transition: transition, title: title, pageUrl: pageUrl } ); | |
urlHistory.activeIndex = urlHistory.stack.length - 1; | |
}, | |
//wipe urls ahead of active index | |
clearForward: function() { | |
urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 ); | |
}, | |
directHashChange: function( opts ) { | |
var back , forward, newActiveIndex; | |
// check if url isp in history and if it's ahead or behind current page | |
$.each( urlHistory.stack, function( i, historyEntry ) { | |
//if the url is in the stack, it's a forward or a back | |
if( opts.currentUrl === historyEntry.url ) { | |
//define back and forward by whether url is older or newer than current page | |
back = i < urlHistory.activeIndex; | |
forward = !back; | |
newActiveIndex = i; | |
} | |
}); | |
// save new page index, null check to prevent falsey 0 result | |
this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex; | |
if( back ) { | |
opts.isBack(); | |
} else if( forward ) { | |
opts.isForward(); | |
} | |
}, | |
//disable hashchange event listener internally to ignore one change | |
//toggled internally when location.hash is updated to match the url of a successful page load | |
ignoreNextHashChange: false | |
}, | |
//define first selector to receive focus when a page is shown | |
focusable = "[tabindex],a,button:visible,select:visible,input", | |
//queue to hold simultanious page transitions | |
pageTransitionQueue = [], | |
//indicates whether or not page is in process of transitioning | |
isPageTransitioning = false, | |
//nonsense hash change key for dialogs, so they create a history entry | |
dialogHashKey = "&ui-state=dialog", | |
//existing base tag? | |
$base = $head.children( "base" ), | |
//tuck away the original document URL minus any fragment. | |
documentUrl = path.parseUrl( location.href ), | |
//if the document has an embedded base tag, documentBase is set to its | |
//initial value. If a base tag does not exist, then we default to the documentUrl. | |
documentBase = $base.length ? path.parseUrl( path.makeUrlAbsolute( $base.attr( "href" ), documentUrl.href ) ) : documentUrl, | |
//cache the comparison once. | |
documentBaseDiffers = ( documentUrl.hrefNoHash !== documentBase.hrefNoHash ); | |
//base element management, defined depending on dynamic base tag support | |
var base = $.support.dynamicBaseTag ? { | |
//define base element, for use in routing asset urls that are referenced in Ajax-requested markup | |
element: ( $base.length ? $base : $( "<base>", { href: documentBase.hrefNoHash } ).prependTo( $head ) ), | |
//set the generated BASE element's href attribute to a new page's base path | |
set: function( href ) { | |
base.element.attr( "href", path.makeUrlAbsolute( href, documentBase ) ); | |
}, | |
//set the generated BASE element's href attribute to a new page's base path | |
reset: function() { | |
base.element.attr( "href", documentBase.hrefNoHash ); | |
} | |
} : undefined; | |
/* | |
internal utility functions | |
--------------------------------------*/ | |
//direct focus to the page title, or otherwise first focusable element | |
function reFocus( page ) { | |
var lastClicked = page.jqmData( "lastClicked" ); | |
if( lastClicked && lastClicked.length ) { | |
lastClicked.focus(); | |
} | |
else { | |
var pageTitle = page.find( ".ui-title:eq(0)" ); | |
if( pageTitle.length ) { | |
pageTitle.focus(); | |
} | |
else{ | |
page.find( focusable ).eq( 0 ).focus(); | |
} | |
} | |
} | |
//remove active classes after page transition or error | |
function removeActiveLinkClass( forceRemoval ) { | |
if( !!$activeClickedLink && ( !$activeClickedLink.closest( '.ui-page-active' ).length || forceRemoval ) ) { | |
$activeClickedLink.removeClass( $.mobile.activeBtnClass ); | |
} | |
$activeClickedLink = null; | |
} | |
function releasePageTransitionLock() { | |
isPageTransitioning = false; | |
if( pageTransitionQueue.length > 0 ) { | |
$.mobile.changePage.apply( null, pageTransitionQueue.pop() ); | |
} | |
} | |
//function for transitioning between two existing pages | |
function transitionPages( toPage, fromPage, transition, reverse ) { | |
//get current scroll distance | |
var currScroll = $.support.scrollTop ? $window.scrollTop() : true, | |
toScroll = toPage.data( "lastScroll" ) || $.mobile.defaultHomeScroll, | |
screenHeight = getScreenHeight(); | |
//if scrolled down, scroll to top | |
if( currScroll ){ | |
window.scrollTo( 0, $.mobile.defaultHomeScroll ); | |
} | |
//if the Y location we're scrolling to is less than 10px, let it go for sake of smoothness | |
if( toScroll < $.mobile.minScrollBack ){ | |
toScroll = 0; | |
} | |
if( fromPage ) { | |
//set as data for returning to that spot | |
fromPage | |
.height( screenHeight + currScroll ) | |
.jqmData( "lastScroll", currScroll ) | |
.jqmData( "lastClicked", $activeClickedLink ); | |
//trigger before show/hide events | |
fromPage.data( "page" )._trigger( "beforehide", null, { nextPage: toPage } ); | |
} | |
toPage | |
.height( screenHeight + toScroll ) | |
.data( "page" )._trigger( "beforeshow", null, { prevPage: fromPage || $( "" ) } ); | |
//clear page loader | |
$.mobile.hidePageLoadingMsg(); | |
//find the transition handler for the specified transition. If there | |
//isn't one in our transitionHandlers dictionary, use the default one. | |
//call the handler immediately to kick-off the transition. | |
var th = $.mobile.transitionHandlers[transition || "none"] || $.mobile.defaultTransitionHandler, | |
promise = th( transition, reverse, toPage, fromPage ); | |
promise.done(function() { | |
//reset toPage height bac | |
toPage.height( "" ); | |
//jump to top or prev scroll, sometimes on iOS the page has not rendered yet. | |
if( toScroll ){ | |
$.mobile.silentScroll( toScroll ); | |
$( document ).one( "silentscroll", function() { reFocus( toPage ); } ); | |
} | |
else{ | |
reFocus( toPage ); | |
} | |
//trigger show/hide events | |
if( fromPage ) { | |
fromPage.height("").data( "page" )._trigger( "hide", null, { nextPage: toPage } ); | |
} | |
//trigger pageshow, define prevPage as either fromPage or empty jQuery obj | |
toPage.data( "page" )._trigger( "show", null, { prevPage: fromPage || $( "" ) } ); | |
}); | |
return promise; | |
} | |
//simply set the active page's minimum height to screen height, depending on orientation | |
function getScreenHeight(){ | |
var orientation = jQuery.event.special.orientationchange.orientation(), | |
port = orientation === "portrait", | |
winMin = port ? 480 : 320, | |
screenHeight = port ? screen.availHeight : screen.availWidth, | |
winHeight = Math.max( winMin, $( window ).height() ), | |
pageMin = Math.min( screenHeight, winHeight ); | |
return pageMin; | |
} | |
//simply set the active page's minimum height to screen height, depending on orientation | |
function resetActivePageHeight(){ | |
$( "." + $.mobile.activePageClass ).css( "min-height", getScreenHeight() ); | |
} | |
//shared page enhancements | |
function enhancePage( $page, role ) { | |
// If a role was specified, make sure the data-role attribute | |
// on the page element is in sync. | |
if( role ) { | |
$page.attr( "data-" + $.mobile.ns + "role", role ); | |
} | |
//run page plugin | |
$page.page(); | |
} | |
/* exposed $.mobile methods */ | |
//animation complete callback | |
$.fn.animationComplete = function( callback ) { | |
if( $.support.cssTransitions ) { | |
return $( this ).one( 'webkitAnimationEnd', callback ); | |
} | |
else{ | |
// defer execution for consistency between webkit/non webkit | |
setTimeout( callback, 0 ); | |
return $( this ); | |
} | |
}; | |
//update location.hash, with or without triggering hashchange event | |
//TODO - deprecate this one at 1.0 | |
$.mobile.updateHash = path.set; | |
//expose path object on $.mobile | |
$.mobile.path = path; | |
//expose base object on $.mobile | |
$.mobile.base = base; | |
//url stack, useful when plugins need to be aware of previous pages viewed | |
//TODO: deprecate this one at 1.0 | |
$.mobile.urlstack = urlHistory.stack; | |
//history stack | |
$.mobile.urlHistory = urlHistory; | |
//default non-animation transition handler | |
$.mobile.noneTransitionHandler = function( name, reverse, $toPage, $fromPage ) { | |
if ( $fromPage ) { | |
$fromPage.removeClass( $.mobile.activePageClass ); | |
} | |
$toPage.addClass( $.mobile.activePageClass ); | |
return $.Deferred().resolve( name, reverse, $toPage, $fromPage ).promise(); | |
}; | |
//default handler for unknown transitions | |
$.mobile.defaultTransitionHandler = $.mobile.noneTransitionHandler; | |
//transition handler dictionary for 3rd party transitions | |
$.mobile.transitionHandlers = { | |
none: $.mobile.defaultTransitionHandler | |
}; | |
//enable cross-domain page support | |
$.mobile.allowCrossDomainPages = false; | |
//return the original document url | |
$.mobile.getDocumentUrl = function(asParsedObject) { | |
return asParsedObject ? $.extend( {}, documentUrl ) : documentUrl.href; | |
}; | |
//return the original document base url | |
$.mobile.getDocumentBase = function(asParsedObject) { | |
return asParsedObject ? $.extend( {}, documentBase ) : documentBase.href; | |
}; | |
// Load a page into the DOM. | |
$.mobile.loadPage = function( url, options ) { | |
// This function uses deferred notifications to let callers | |
// know when the page is done loading, or if an error has occurred. | |
var deferred = $.Deferred(), | |
// The default loadPage options with overrides specified by | |
// the caller. | |
settings = $.extend( {}, $.mobile.loadPage.defaults, options ), | |
// The DOM element for the page after it has been loaded. | |
page = null, | |
// If the reloadPage option is true, and the page is already | |
// in the DOM, dupCachedPage will be set to the page element | |
// so that it can be removed after the new version of the | |
// page is loaded off the network. | |
dupCachedPage = null, | |
// determine the current base url | |
findBaseWithDefault = function(){ | |
var closestBase = ( $.mobile.activePage && getClosestBaseUrl( $.mobile.activePage ) ); | |
return closestBase || documentBase.hrefNoHash; | |
}, | |
// The absolute version of the URL passed into the function. This | |
// version of the URL may contain dialog/subpage params in it. | |
absUrl = path.makeUrlAbsolute( url, findBaseWithDefault() ); | |
// If the caller provided data, and we're using "get" request, | |
// append the data to the URL. | |
if ( settings.data && settings.type === "get" ) { | |
absUrl = path.addSearchParams( absUrl, settings.data ); | |
settings.data = undefined; | |
} | |
// The absolute version of the URL minus any dialog/subpage params. | |
// In otherwords the real URL of the page to be loaded. | |
var fileUrl = path.getFilePath( absUrl ), | |
// The version of the Url actually stored in the data-url attribute of | |
// the page. For embedded pages, it is just the id of the page. For pages | |
// within the same domain as the document base, it is the site relative | |
// path. For cross-domain pages (Phone Gap only) the entire absolute Url | |
// used to load the page. | |
dataUrl = path.convertUrlToDataUrl( absUrl ); | |
// Make sure we have a pageContainer to work with. | |
settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; | |
// Check to see if the page already exists in the DOM. | |
page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" ); | |
// Reset base to the default document base. | |
if ( base ) { | |
base.reset(); | |
} | |
// If the page we are interested in is already in the DOM, | |
// and the caller did not indicate that we should force a | |
// reload of the file, we are done. Otherwise, track the | |
// existing page as a duplicated. | |
if ( page.length ) { | |
if ( !settings.reloadPage ) { | |
enhancePage( page, settings.role ); | |
deferred.resolve( absUrl, options, page ); | |
return deferred.promise(); | |
} | |
dupCachedPage = page; | |
} | |
if ( settings.showLoadMsg ) { | |
// This configurable timeout allows cached pages a brief delay to load without showing a message | |
var loadMsgDelay = setTimeout(function(){ | |
$.mobile.showPageLoadingMsg(); | |
}, settings.loadMsgDelay ), | |
// Shared logic for clearing timeout and removing message. | |
hideMsg = function(){ | |
// Stop message show timer | |
clearTimeout( loadMsgDelay ); | |
// Hide loading message | |
$.mobile.hidePageLoadingMsg(); | |
}; | |
} | |
if ( !( $.mobile.allowCrossDomainPages || path.isSameDomain( documentUrl, absUrl ) ) ) { | |
deferred.reject( absUrl, options ); | |
} else { | |
// Load the new page. | |
$.ajax({ | |
url: fileUrl, | |
type: settings.type, | |
data: settings.data, | |
dataType: "html", | |
success: function( html ) { | |
//pre-parse html to check for a data-url, | |
//use it as the new fileUrl, base path, etc | |
var all = $( "<div></div>" ), | |
//page title regexp | |
newPageTitle = html.match( /<title[^>]*>([^<]*)/ ) && RegExp.$1, | |
// TODO handle dialogs again | |
pageElemRegex = new RegExp( ".*(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>).*" ), | |
dataUrlRegex = new RegExp( "\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?" ); | |
// data-url must be provided for the base tag so resource requests can be directed to the | |
// correct url. loading into a temprorary element makes these requests immediately | |
if( pageElemRegex.test( html ) | |
&& RegExp.$1 | |
&& dataUrlRegex.test( RegExp.$1 ) | |
&& RegExp.$1 ) { | |
url = fileUrl = path.getFilePath( RegExp.$1 ); | |
} | |
else{ | |
} | |
if ( base ) { | |
base.set( fileUrl ); | |
} | |
//workaround to allow scripts to execute when included in page divs | |
all.get( 0 ).innerHTML = html; | |
page = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first(); | |
//if page elem couldn't be found, create one and insert the body element's contents | |
if( !page.length ){ | |
page = $( "<div data-" + $.mobile.ns + "role='page'>" + html.split( /<\/?body[^>]*>/gmi )[1] + "</div>" ); | |
} | |
if ( newPageTitle && !page.jqmData( "title" ) ) { | |
page.jqmData( "title", newPageTitle ); | |
} | |
//rewrite src and href attrs to use a base url | |
if( !$.support.dynamicBaseTag ) { | |
var newPath = path.get( fileUrl ); | |
page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() { | |
var thisAttr = $( this ).is( '[href]' ) ? 'href' : | |
$(this).is('[src]') ? 'src' : 'action', | |
thisUrl = $( this ).attr( thisAttr ); | |
// XXX_jblas: We need to fix this so that it removes the document | |
// base URL, and then prepends with the new page URL. | |
//if full path exists and is same, chop it - helps IE out | |
thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' ); | |
if( !/^(\w+:|#|\/)/.test( thisUrl ) ) { | |
$( this ).attr( thisAttr, newPath + thisUrl ); | |
} | |
}); | |
} | |
//append to page and enhance | |
page | |
.attr( "data-" + $.mobile.ns + "url", path.convertUrlToDataUrl( fileUrl ) ) | |
.appendTo( settings.pageContainer ); | |
// wait for page creation to leverage options defined on widget | |
page.one('pagecreate', function(){ | |
// when dom caching is not enabled bind to remove the page on hide | |
if( !page.data("page").options.domCache ){ | |
page.bind( "pagehide.remove", function(){ | |
$(this).remove(); | |
}); | |
} | |
}); | |
enhancePage( page, settings.role ); | |
// Enhancing the page may result in new dialogs/sub pages being inserted | |
// into the DOM. If the original absUrl refers to a sub-page, that is the | |
// real page we are interested in. | |
if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) { | |
page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" ); | |
} | |
//bind pageHide to removePage after it's hidden, if the page options specify to do so | |
// Remove loading message. | |
if ( settings.showLoadMsg ) { | |
hideMsg(); | |
} | |
deferred.resolve( absUrl, options, page, dupCachedPage ); | |
}, | |
error: function() { | |
//set base back to current path | |
if( base ) { | |
base.set( path.get() ); | |
} | |
// Remove loading message. | |
if ( settings.showLoadMsg ) { | |
// Remove loading message. | |
hideMsg(); | |
//show error message | |
$( "<div class='ui-loader ui-overlay-shadow ui-body-e ui-corner-all'><h1>"+ $.mobile.pageLoadErrorMessage +"</h1></div>" ) | |
.css({ "display": "block", "opacity": 0.96, "top": $window.scrollTop() + 100 }) | |
.appendTo( settings.pageContainer ) | |
.delay( 800 ) | |
.fadeOut( 400, function() { | |
$( this ).remove(); | |
}); | |
} | |
deferred.reject( absUrl, options ); | |
} | |
}); | |
} | |
return deferred.promise(); | |
}; | |
$.mobile.loadPage.defaults = { | |
type: "get", | |
data: undefined, | |
reloadPage: false, | |
role: undefined, // By default we rely on the role defined by the @data-role attribute. | |
showLoadMsg: false, | |
pageContainer: undefined, | |
loadMsgDelay: 50 // This delay allows loads that pull from browser cache to occur without showing the loading message. | |
}; | |
// Show a specific page in the page container. | |
$.mobile.changePage = function( toPage, options ) { | |
// XXX: REMOVE_BEFORE_SHIPPING_1.0 | |
// This is temporary code that makes changePage() compatible with previous alpha versions. | |
if ( typeof options !== "object" ) { | |
var opts = null; | |
// Map old-style call signature for form submit to the new options object format. | |
if ( typeof toPage === "object" && toPage.url && toPage.type ) { | |
opts = { | |
type: toPage.type, | |
data: toPage.data, | |
forcePageLoad: true | |
}; | |
toPage = toPage.url; | |
} | |
// The arguments passed into the function need to be re-mapped | |
// to the new options object format. | |
var len = arguments.length; | |
if ( len > 1 ) { | |
var argNames = [ "transition", "reverse", "changeHash", "fromHashChange" ], i; | |
for ( i = 1; i < len; i++ ) { | |
var a = arguments[ i ]; | |
if ( typeof a !== "undefined" ) { | |
opts = opts || {}; | |
opts[ argNames[ i - 1 ] ] = a; | |
} | |
} | |
} | |
// If an options object was created, then we know changePage() was called | |
// with an old signature. | |
if ( opts ) { | |
return $.mobile.changePage( toPage, opts ); | |
} | |
} | |
// XXX: REMOVE_BEFORE_SHIPPING_1.0 | |
// If we are in the midst of a transition, queue the current request. | |
// We'll call changePage() once we're done with the current transition to | |
// service the request. | |
if( isPageTransitioning ) { | |
pageTransitionQueue.unshift( arguments ); | |
return; | |
} | |
// Set the isPageTransitioning flag to prevent any requests from | |
// entering this method while we are in the midst of loading a page | |
// or transitioning. | |
isPageTransitioning = true; | |
var settings = $.extend( {}, $.mobile.changePage.defaults, options ); | |
// Make sure we have a pageContainer to work with. | |
settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; | |
// If the caller passed us a url, call loadPage() | |
// to make sure it is loaded into the DOM. We'll listen | |
// to the promise object it returns so we know when | |
// it is done loading or if an error ocurred. | |
if ( typeof toPage == "string" ) { | |
$.mobile.loadPage( toPage, settings ) | |
.done(function( url, options, newPage, dupCachedPage ) { | |
isPageTransitioning = false; | |
options.duplicateCachedPage = dupCachedPage; | |
$.mobile.changePage( newPage, options ); | |
}) | |
.fail(function( url, options ) { | |
// XXX_jblas: Fire off changepagefailed notificaiton. | |
isPageTransitioning = false; | |
//clear out the active button state | |
removeActiveLinkClass( true ); | |
//release transition lock so navigation is free again | |
releasePageTransitionLock(); | |
settings.pageContainer.trigger("changepagefailed"); | |
}); | |
return; | |
} | |
// The caller passed us a real page DOM element. Update our | |
// internal state and then trigger a transition to the page. | |
var mpc = settings.pageContainer, | |
fromPage = $.mobile.activePage, | |
url = toPage.jqmData( "url" ), | |
// The pageUrl var is usually the same as url, except when url is obscured as a dialog url. pageUrl always contains the file path | |
pageUrl = url, | |
fileUrl = path.getFilePath( url ), | |
active = urlHistory.getActive(), | |
activeIsInitialPage = urlHistory.activeIndex === 0, | |
historyDir = 0, | |
pageTitle = document.title, | |
isDialog = settings.role === "dialog" || toPage.jqmData( "role" ) === "dialog"; | |
// Let listeners know we're about to change the current page. | |
mpc.trigger( "beforechangepage" ); | |
// If we are trying to transition to the same page that we are currently on ignore the request. | |
// an illegal same page request is defined by the current page being the same as the url, as long as there's history | |
// and toPage is not an array or object (those are allowed to be "same") | |
// | |
// XXX_jblas: We need to remove this at some point when we allow for transitions | |
// to the same page. | |
if( fromPage && fromPage[0] === toPage[0] ) { | |
isPageTransitioning = false; | |
mpc.trigger( "changepage" ); | |
return; | |
} | |
// We need to make sure the page we are given has already been enhanced. | |
enhancePage( toPage, settings.role ); | |
// If the changePage request was sent from a hashChange event, check to see if the | |
// page is already within the urlHistory stack. If so, we'll assume the user hit | |
// the forward/back button and will try to match the transition accordingly. | |
if( settings.fromHashChange ) { | |
urlHistory.directHashChange({ | |
currentUrl: url, | |
isBack: function() { historyDir = -1; }, | |
isForward: function() { historyDir = 1; } | |
}); | |
} | |
// Kill the keyboard. | |
// XXX_jblas: We need to stop crawling the entire document to kill focus. Instead, | |
// we should be tracking focus with a live() handler so we already have | |
// the element in hand at this point. | |
// Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement | |
// is undefined when we are in an IFrame. | |
try { | |
$( document.activeElement || "" ).add( "input:focus, textarea:focus, select:focus" ).blur(); | |
} catch(e) {} | |
// If we're displaying the page as a dialog, we don't want the url | |
// for the dialog content to be used in the hash. Instead, we want | |
// to append the dialogHashKey to the url of the current page. | |
if ( isDialog && active ) { | |
url = active.url + dialogHashKey; | |
} | |
// Set the location hash. | |
if( settings.changeHash !== false && url ) { | |
//disable hash listening temporarily | |
urlHistory.ignoreNextHashChange = true; | |
//update hash and history | |
path.set( url ); | |
} | |
//if title element wasn't found, try the page div data attr too | |
var newPageTitle = toPage.jqmData( "title" ) || toPage.children(":jqmData(role='header')").find(".ui-title" ).text(); | |
if( !!newPageTitle && pageTitle == document.title ) { | |
pageTitle = newPageTitle; | |
} | |
//add page to history stack if it's not back or forward | |
if( !historyDir ) { | |
urlHistory.addNew( url, settings.transition, pageTitle, pageUrl ); | |
} | |
//set page title | |
document.title = urlHistory.getActive().title; | |
//set "toPage" as activePage | |
$.mobile.activePage = toPage; | |
// Make sure we have a transition defined. | |
settings.transition = settings.transition | |
|| ( ( historyDir && !activeIsInitialPage ) ? active.transition : undefined ) | |
|| ( isDialog ? $.mobile.defaultDialogTransition : $.mobile.defaultPageTransition ); | |
// If we're navigating back in the URL history, set reverse accordingly. | |
settings.reverse = settings.reverse || historyDir < 0; | |
transitionPages( toPage, fromPage, settings.transition, settings.reverse ) | |
.done(function() { | |
removeActiveLinkClass(); | |
//if there's a duplicateCachedPage, remove it from the DOM now that it's hidden | |
if ( settings.duplicateCachedPage ) { | |
settings.duplicateCachedPage.remove(); | |
} | |
//remove initial build class (only present on first pageshow) | |
$html.removeClass( "ui-mobile-rendering" ); | |
releasePageTransitionLock(); | |
// Let listeners know we're all done changing the current page. | |
mpc.trigger( "changepage" ); | |
}); | |
}; | |
$.mobile.changePage.defaults = { | |
transition: undefined, | |
reverse: false, | |
changeHash: true, | |
fromHashChange: false, | |
role: undefined, // By default we rely on the role defined by the @data-role attribute. | |
duplicateCachedPage: undefined, | |
pageContainer: undefined, | |
showLoadMsg: true //loading message shows by default when pages are being fetched during changePage | |
}; | |
/* Event Bindings - hashchange, submit, and click */ | |
function findClosestLink( ele ) | |
{ | |
while ( ele ) { | |
if ( ele.nodeName.toLowerCase() == "a" ) { | |
break; | |
} | |
ele = ele.parentNode; | |
} | |
return ele; | |
} | |
// The base URL for any given element depends on the page it resides in. | |
function getClosestBaseUrl( ele ) | |
{ | |
// Find the closest page and extract out its url. | |
var url = $( ele ).closest( ".ui-page" ).jqmData( "url" ), | |
base = documentBase.hrefNoHash; | |
if ( !url || !path.isPath( url ) ) { | |
url = base; | |
} | |
return path.makeUrlAbsolute( url, base); | |
} | |
//The following event bindings should be bound after mobileinit has been triggered | |
//the following function is called in the init file | |
$.mobile._registerInternalEvents = function(){ | |
//bind to form submit events, handle with Ajax | |
$( "form" ).live('submit', function( event ) { | |
var $this = $( this ); | |
if( !$.mobile.ajaxEnabled || | |
$this.is( ":jqmData(ajax='false')" ) ) { | |
return; | |
} | |
var type = $this.attr( "method" ), | |
target = $this.attr( "target" ), | |
url = $this.attr( "action" ); | |
// If no action is specified, browsers default to using the | |
// URL of the document containing the form. Since we dynamically | |
// pull in pages from external documents, the form should submit | |
// to the URL for the source document of the page containing | |
// the form. | |
if ( !url ) { | |
// Get the @data-url for the page containing the form. | |
url = getClosestBaseUrl( $this ); | |
if ( url === documentBase.hrefNoHash ) { | |
// The url we got back matches the document base, | |
// which means the page must be an internal/embedded page, | |
// so default to using the actual document url as a browser | |
// would. | |
url = documentUrl.hrefNoSearch; | |
} | |
} | |
url = path.makeUrlAbsolute( url, getClosestBaseUrl($this) ); | |
//external submits use regular HTTP | |
if( path.isExternal( url ) || target ) { | |
return; | |
} | |
$.mobile.changePage( | |
url, | |
{ | |
type: type && type.length && type.toLowerCase() || "get", | |
data: $this.serialize(), | |
transition: $this.jqmData( "transition" ), | |
direction: $this.jqmData( "direction" ), | |
reloadPage: true | |
} | |
); | |
event.preventDefault(); | |
}); | |
//add active state on vclick | |
$( document ).bind( "vclick", function( event ) { | |
var link = findClosestLink( event.target ); | |
if ( link ) { | |
if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) { | |
$( link ).closest( ".ui-btn" ).not( ".ui-disabled" ).addClass( $.mobile.activeBtnClass ); | |
$( "." + $.mobile.activePageClass + " .ui-btn" ).not( link ).blur(); | |
} | |
} | |
}); | |
// click routing - direct to HTTP or Ajax, accordingly | |
$( document ).bind( "click", function( event ) { | |
var link = findClosestLink( event.target ); | |
if ( !link ) { | |
return; | |
} | |
var $link = $( link ), | |
//remove active link class if external (then it won't be there if you come back) | |
httpCleanup = function(){ | |
window.setTimeout( function() { removeActiveLinkClass( true ); }, 200 ); | |
}; | |
//if there's a data-rel=back attr, go back in history | |
if( $link.is( ":jqmData(rel='back')" ) ) { | |
window.history.back(); | |
return false; | |
} | |
//if ajax is disabled, exit early | |
if( !$.mobile.ajaxEnabled ){ | |
httpCleanup(); | |
//use default click handling | |
return; | |
} | |
var baseUrl = getClosestBaseUrl( $link ), | |
//get href, if defined, otherwise default to empty hash | |
href = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl ); | |
// XXX_jblas: Ideally links to application pages should be specified as | |
// an url to the application document with a hash that is either | |
// the site relative path or id to the page. But some of the | |
// internal code that dynamically generates sub-pages for nested | |
// lists and select dialogs, just write a hash in the link they | |
// create. This means the actual URL path is based on whatever | |
// the current value of the base tag is at the time this code | |
// is called. For now we are just assuming that any url with a | |
// hash in it is an application page reference. | |
if ( href.search( "#" ) != -1 ) { | |
href = href.replace( /[^#]*#/, "" ); | |
if ( !href ) { | |
//link was an empty hash meant purely | |
//for interaction, so we ignore it. | |
event.preventDefault(); | |
return; | |
} else if ( path.isPath( href ) ) { | |
//we have apath so make it the href we want to load. | |
href = path.makeUrlAbsolute( href, baseUrl ); | |
} else { | |
//we have a simple id so use the documentUrl as its base. | |
href = path.makeUrlAbsolute( "#" + href, documentUrl.hrefNoHash ); | |
} | |
} | |
// Should we handle this link, or let the browser deal with it? | |
var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ), | |
// Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR | |
// requests if the document doing the request was loaded via the file:// protocol. | |
// This is usually to allow the application to "phone home" and fetch app specific | |
// data. We normally let the browser handle external/cross-domain urls, but if the | |
// allowCrossDomainPages option is true, we will allow cross-domain http/https | |
// requests to go through our page loading logic. | |
isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && href.search( /^https?:/ ) != -1 ), | |
//check for protocol or rel and its not an embedded page | |
//TODO overlap in logic from isExternal, rel=external check should be | |
// moved into more comprehensive isExternalLink | |
isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !isCrossDomainPageLoad ); | |
$activeClickedLink = $link.closest( ".ui-btn" ); | |
if( isExternal ) { | |
httpCleanup(); | |
//use default click handling | |
return; | |
} | |
//use ajax | |
var transition = $link.jqmData( "transition" ), | |
direction = $link.jqmData( "direction" ), | |
reverse = ( direction && direction === "reverse" ) || | |
// deprecated - remove by 1.0 | |
$link.jqmData( "back" ), | |
//this may need to be more specific as we use data-rel more | |
role = $link.attr( "data-" + $.mobile.ns + "rel" ) || undefined; | |
$.mobile.changePage( href, { transition: transition, reverse: reverse, role: role } ); | |
event.preventDefault(); | |
}); | |
//prefetch pages when anchors with data-prefetch are encountered | |
$( ".ui-page" ).live( "pageshow.prefetch", function(){ | |
var urls = []; | |
$( this ).find( "a:jqmData(prefetch)" ).each(function(){ | |
var url = $( this ).attr( "href" ); | |
if ( url && $.inArray( url, urls ) === -1 ) { | |
urls.push( url ); | |
$.mobile.loadPage( url ); | |
} | |
}); | |
} ); | |
//hashchange event handler | |
$window.bind( "hashchange", function( e, triggered ) { | |
//find first page via hash | |
var to = path.stripHash( location.hash ), | |
//transition is false if it's the first page, undefined otherwise (and may be overridden by default) | |
transition = $.mobile.urlHistory.stack.length === 0 ? "none" : undefined; | |
//if listening is disabled (either globally or temporarily), or it's a dialog hash | |
if( !$.mobile.hashListeningEnabled || urlHistory.ignoreNextHashChange ) { | |
urlHistory.ignoreNextHashChange = false; | |
return; | |
} | |
// special case for dialogs | |
if( urlHistory.stack.length > 1 && | |
to.indexOf( dialogHashKey ) > -1 ) { | |
// If current active page is not a dialog skip the dialog and continue | |
// in the same direction | |
if(!$.mobile.activePage.is( ".ui-dialog" )) { | |
//determine if we're heading forward or backward and continue accordingly past | |
//the current dialog | |
urlHistory.directHashChange({ | |
currentUrl: to, | |
isBack: function() { window.history.back(); }, | |
isForward: function() { window.history.forward(); } | |
}); | |
// prevent changepage | |
return; | |
} else { | |
var setTo = function() { to = $.mobile.urlHistory.getActive().pageUrl; }; | |
// if the current active page is a dialog and we're navigating | |
// to a dialog use the dialog objected saved in the stack | |
urlHistory.directHashChange({ currentUrl: to, isBack: setTo, isForward: setTo }); | |
} | |
} | |
//if to is defined, load it | |
if ( to ) { | |
to = ( typeof to === "string" && !path.isPath( to ) ) ? ( '#' + to ) : to; | |
$.mobile.changePage( to, { transition: transition, changeHash: false, fromHashChange: true } ); | |
} | |
//there's no hash, go to the first page in the dom | |
else { | |
$.mobile.changePage( $.mobile.firstPage, { transition: transition, changeHash: false, fromHashChange: true } ); | |
} | |
}); | |
//set page min-heights to be device specific | |
$( document ).bind( "pageshow", resetActivePageHeight ); | |
$( window ).bind( "throttledresize", resetActivePageHeight ); | |
};//_registerInternalEvents callback | |
})( jQuery ); | |
/*! | |
* jQuery Mobile v@VERSION | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
function css3TransitionHandler( name, reverse, $to, $from ) { | |
var deferred = new $.Deferred(), | |
reverseClass = reverse ? " reverse" : "", | |
viewportClass = "ui-mobile-viewport-transitioning viewport-" + name, | |
doneFunc = function() { | |
$to.add( $from ).removeClass( "out in reverse " + name ); | |
if ( $from ) { | |
$from.removeClass( $.mobile.activePageClass ); | |
} | |
$to.parent().removeClass( viewportClass ); | |
deferred.resolve( name, reverse, $to, $from ); | |
}; | |
$to.animationComplete( doneFunc ); | |
$to.parent().addClass( viewportClass ); | |
if ( $from ) { | |
$from.addClass( name + " out" + reverseClass ); | |
} | |
$to.addClass( $.mobile.activePageClass + " " + name + " in" + reverseClass ); | |
return deferred.promise(); | |
} | |
// Make our transition handler public. | |
$.mobile.css3TransitionHandler = css3TransitionHandler; | |
// If the default transition handler is the 'none' handler, replace it with our handler. | |
if ( $.mobile.defaultTransitionHandler === $.mobile.noneTransitionHandler ) { | |
$.mobile.defaultTransitionHandler = css3TransitionHandler; | |
} | |
})( jQuery, this ); | |
/* | |
* jQuery Mobile Framework : "degradeInputs" plugin - degrades inputs to another type after custom enhancements are made. | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.mobile.page.prototype.options.degradeInputs = { | |
color: false, | |
date: false, | |
datetime: false, | |
"datetime-local": false, | |
email: false, | |
month: false, | |
number: false, | |
range: "number", | |
search: true, | |
tel: false, | |
time: false, | |
url: false, | |
week: false | |
}; | |
$.mobile.page.prototype.options.keepNative = ":jqmData(role='none'), :jqmData(role='nojs')"; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate enhance", function( e ){ | |
var page = $( e.target ).data( "page" ), | |
o = page.options; | |
// degrade inputs to avoid poorly implemented native functionality | |
$( e.target ).find( "input" ).not( o.keepNative ).each(function() { | |
var $this = $( this ), | |
type = this.getAttribute( "type" ), | |
optType = o.degradeInputs[ type ] || "text"; | |
if ( o.degradeInputs[ type ] ) { | |
$this.replaceWith( | |
$( "<div>" ).html( $this.clone() ).html() | |
.replace( /\s+type=["']?\w+['"]?/, " type=\"" + optType + "\" data-" + $.mobile.ns + "type=\"" + type + "\" " ) | |
); | |
} | |
}); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "dialog" plugin. | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
(function( $, window, undefined ) { | |
$.widget( "mobile.dialog", $.mobile.widget, { | |
options: { | |
closeBtnText : "Close", | |
theme : "a", | |
initSelector : ":jqmData(role='dialog')" | |
}, | |
_create: function() { | |
var $el = this.element, | |
pageTheme = $el.attr( "class" ).match( /ui-body-[a-z]/ ); | |
if( pageTheme.length ){ | |
$el.removeClass( pageTheme[ 0 ] ); | |
} | |
$el.addClass( "ui-body-" + this.options.theme ); | |
// Class the markup for dialog styling | |
// Set aria role | |
$el.attr( "role", "dialog" ) | |
.addClass( "ui-dialog" ) | |
.find( ":jqmData(role='header')" ) | |
.addClass( "ui-corner-top ui-overlay-shadow" ) | |
.prepend( "<a href='#' data-" + $.mobile.ns + "icon='delete' data-" + $.mobile.ns + "rel='back' data-" + $.mobile.ns + "iconpos='notext'>"+ this.options.closeBtnText + "</a>" ) | |
.end() | |
.find( ":jqmData(role='content'),:jqmData(role='footer')" ) | |
.last() | |
.addClass( "ui-corner-bottom ui-overlay-shadow" ); | |
/* bind events | |
- clicks and submits should use the closing transition that the dialog opened with | |
unless a data-transition is specified on the link/form | |
- if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally | |
*/ | |
$el.bind( "vclick submit", function( event ) { | |
var $target = $( event.target ).closest( event.type === "vclick" ? "a" : "form" ), | |
active; | |
if ( $target.length && !$target.jqmData( "transition" ) ) { | |
active = $.mobile.urlHistory.getActive() || {}; | |
$target.attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) ) | |
.attr( "data-" + $.mobile.ns + "direction", "reverse" ); | |
} | |
}) | |
.bind( "pagehide", function() { | |
$( this ).find( "." + $.mobile.activeBtnClass ).removeClass( $.mobile.activeBtnClass ); | |
}); | |
}, | |
// Close method goes back in history | |
close: function() { | |
window.history.back(); | |
} | |
}); | |
//auto self-init widgets | |
$( $.mobile.dialog.prototype.options.initSelector ).live( "pagecreate", function(){ | |
$( this ).dialog(); | |
}); | |
})( jQuery, this ); | |
/* | |
* jQuery Mobile Framework : This plugin handles theming and layout of headers, footers, and content areas | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.mobile.page.prototype.options.backBtnText = "Back"; | |
$.mobile.page.prototype.options.addBackBtn = false; | |
$.mobile.page.prototype.options.backBtnTheme = null; | |
$.mobile.page.prototype.options.headerTheme = "a"; | |
$.mobile.page.prototype.options.footerTheme = "a"; | |
$.mobile.page.prototype.options.contentTheme = null; | |
$( ":jqmData(role='page'), :jqmData(role='dialog')" ).live( "pagecreate", function( e ) { | |
var $page = $( this ), | |
o = $page.data( "page" ).options, | |
pageTheme = o.theme; | |
$( ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')", this ).each(function() { | |
var $this = $( this ), | |
role = $this.jqmData( "role" ), | |
theme = $this.jqmData( "theme" ), | |
$headeranchors, | |
leftbtn, | |
rightbtn, | |
backBtn; | |
$this.addClass( "ui-" + role ); | |
//apply theming and markup modifications to page,header,content,footer | |
if ( role === "header" || role === "footer" ) { | |
var thisTheme = theme || ( role === "header" ? o.headerTheme : o.footerTheme ) || pageTheme; | |
//add theme class | |
$this.addClass( "ui-bar-" + thisTheme ); | |
// Add ARIA role | |
$this.attr( "role", role === "header" ? "banner" : "contentinfo" ); | |
// Right,left buttons | |
$headeranchors = $this.children( "a" ); | |
leftbtn = $headeranchors.hasClass( "ui-btn-left" ); | |
rightbtn = $headeranchors.hasClass( "ui-btn-right" ); | |
if ( !leftbtn ) { | |
leftbtn = $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length; | |
} | |
if ( !rightbtn ) { | |
rightbtn = $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length; | |
} | |
// Auto-add back btn on pages beyond first view | |
if ( o.addBackBtn && role === "header" && | |
$( ".ui-page" ).length > 1 && | |
$this.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) && | |
!leftbtn ) { | |
backBtn = $( "<a href='#' class='ui-btn-left' data-"+ $.mobile.ns +"rel='back' data-"+ $.mobile.ns +"icon='arrow-l'>"+ o.backBtnText +"</a>" ).prependTo( $this ); | |
// If theme is provided, override default inheritance | |
backBtn.attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme || thisTheme ); | |
} | |
// Page title | |
$this.children( "h1, h2, h3, h4, h5, h6" ) | |
.addClass( "ui-title" ) | |
// Regardless of h element number in src, it becomes h1 for the enhanced page | |
.attr({ | |
"tabindex": "0", | |
"role": "heading", | |
"aria-level": "1" | |
}); | |
} else if ( role === "content" ) { | |
$this.addClass( "ui-body-" + ( theme || pageTheme || o.contentTheme ) ); | |
// Add ARIA role | |
$this.attr( "role", "main" ); | |
} | |
}); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "collapsible" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.collapsible", $.mobile.widget, { | |
options: { | |
expandCueText: " click to expand contents", | |
collapseCueText: " click to collapse contents", | |
collapsed: false, | |
heading: ">:header,>legend", | |
theme: null, | |
iconTheme: "d", | |
initSelector: ":jqmData(role='collapsible')" | |
}, | |
_create: function() { | |
var $el = this.element, | |
o = this.options, | |
collapsibleContain = $el.addClass( "ui-collapsible-contain" ), | |
collapsibleHeading = $el.find( o.heading ).eq( 0 ), | |
collapsibleContent = collapsibleContain.wrapInner( "<div class='ui-collapsible-content'></div>" ).find( ".ui-collapsible-content" ), | |
collapsibleParent = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" ); | |
// Replace collapsibleHeading if it's a legend | |
if ( collapsibleHeading.is( "legend" ) ) { | |
collapsibleHeading = $( "<div role='heading'>"+ collapsibleHeading.html() +"</div>" ).insertBefore( collapsibleHeading ); | |
collapsibleHeading.next().remove(); | |
} | |
collapsibleHeading | |
//drop heading in before content | |
.insertBefore( collapsibleContent ) | |
//modify markup & attributes | |
.addClass( "ui-collapsible-heading" ) | |
.append( "<span class='ui-collapsible-heading-status'></span>" ) | |
.wrapInner( "<a href='#' class='ui-collapsible-heading-toggle'></a>" ) | |
.find( "a:eq(0)" ) | |
.buttonMarkup({ | |
shadow: !collapsibleParent.length, | |
corners: false, | |
iconPos: "left", | |
icon: "plus", | |
theme: o.theme | |
}) | |
.find( ".ui-icon" ) | |
.removeAttr( "class" ) | |
.buttonMarkup({ | |
shadow: true, | |
corners: true, | |
iconPos: "notext", | |
icon: "plus", | |
theme: o.iconTheme | |
}); | |
if ( !collapsibleParent.length ) { | |
collapsibleHeading | |
.find( "a:eq(0)" ) | |
.addClass( "ui-corner-all" ) | |
.find( ".ui-btn-inner" ) | |
.addClass( "ui-corner-all" ); | |
} else { | |
if ( collapsibleContain.jqmData( "collapsible-last" ) ) { | |
collapsibleHeading | |
.find( "a:eq(0), .ui-btn-inner" ) | |
.addClass( "ui-corner-bottom" ); | |
} | |
} | |
//events | |
collapsibleContain | |
.bind( "collapse", function( event ) { | |
if ( ! event.isDefaultPrevented() && | |
$( event.target ).closest( ".ui-collapsible-contain" ).is( collapsibleContain ) ) { | |
event.preventDefault(); | |
collapsibleHeading | |
.addClass( "ui-collapsible-heading-collapsed" ) | |
.find( ".ui-collapsible-heading-status" ) | |
.text( o.expandCueText ) | |
.end() | |
.find( ".ui-icon" ) | |
.removeClass( "ui-icon-minus" ) | |
.addClass( "ui-icon-plus" ); | |
collapsibleContent.addClass( "ui-collapsible-content-collapsed" ).attr( "aria-hidden", true ); | |
if ( collapsibleContain.jqmData( "collapsible-last" ) ) { | |
collapsibleHeading | |
.find( "a:eq(0), .ui-btn-inner" ) | |
.addClass( "ui-corner-bottom" ); | |
} | |
} | |
}) | |
.bind( "expand", function( event ) { | |
if ( !event.isDefaultPrevented() ) { | |
event.preventDefault(); | |
collapsibleHeading | |
.removeClass( "ui-collapsible-heading-collapsed" ) | |
.find( ".ui-collapsible-heading-status" ).text( o.collapseCueText ); | |
collapsibleHeading.find( ".ui-icon" ).removeClass( "ui-icon-plus" ).addClass( "ui-icon-minus" ); | |
collapsibleContent.removeClass( "ui-collapsible-content-collapsed" ).attr( "aria-hidden", false ); | |
if ( collapsibleContain.jqmData( "collapsible-last" ) ) { | |
collapsibleHeading | |
.find( "a:eq(0), .ui-btn-inner" ) | |
.removeClass( "ui-corner-bottom" ); | |
} | |
} | |
}) | |
.trigger( o.collapsed ? "collapse" : "expand" ); | |
// Close others in a set | |
if ( collapsibleParent.length && !collapsibleParent.jqmData( "collapsiblebound" ) ) { | |
collapsibleParent | |
.jqmData( "collapsiblebound", true ) | |
.bind( "expand", function( event ) { | |
$( event.target ) | |
.closest( ".ui-collapsible-contain" ) | |
.siblings( ".ui-collapsible-contain" ) | |
.trigger( "collapse" ); | |
}); | |
var set = collapsibleParent.children( ":jqmData(role='collapsible')" ); | |
set.first() | |
.find( "a:eq(0)" ) | |
.addClass( "ui-corner-top" ) | |
.find( ".ui-btn-inner" ) | |
.addClass( "ui-corner-top" ); | |
set.last().jqmData( "collapsible-last", true ); | |
} | |
collapsibleHeading | |
.bind( "vclick", function( event ) { | |
var type = collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ? | |
"expand" : "collapse"; | |
collapsibleContain.trigger( type ); | |
event.preventDefault(); | |
}); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.collapsible.prototype.options.initSelector, e.target ).collapsible(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "fieldcontain" plugin - simple class additions to make form row separators | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.fn.fieldcontain = function( options ) { | |
return this.addClass( "ui-field-contain ui-body ui-br" ); | |
}; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='fieldcontain')", e.target ).fieldcontain(); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : plugin for creating CSS grids | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.fn.grid = function( options ) { | |
return this.each(function() { | |
var $this = $( this ), | |
o = $.extend({ | |
grid: null | |
},options), | |
$kids = $this.children(), | |
gridCols = {solo:1, a:2, b:3, c:4, d:5}, | |
grid = o.grid, | |
iterator; | |
if ( !grid ) { | |
if ( $kids.length <= 5 ) { | |
for ( var letter in gridCols ) { | |
if ( gridCols[ letter ] === $kids.length ) { | |
grid = letter; | |
} | |
} | |
} else { | |
grid = "a"; | |
} | |
} | |
iterator = gridCols[grid]; | |
$this.addClass( "ui-grid-" + grid ); | |
$kids.filter( ":nth-child(" + iterator + "n+1)" ).addClass( "ui-block-a" ); | |
if ( iterator > 1 ) { | |
$kids.filter( ":nth-child(" + iterator + "n+2)" ).addClass( "ui-block-b" ); | |
} | |
if ( iterator > 2 ) { | |
$kids.filter( ":nth-child(3n+3)" ).addClass( "ui-block-c" ); | |
} | |
if ( iterator > 3 ) { | |
$kids.filter( ":nth-child(4n+4)" ).addClass( "ui-block-d" ); | |
} | |
if ( iterator > 4 ) { | |
$kids.filter( ":nth-child(5n+5)" ).addClass( "ui-block-e" ); | |
} | |
}); | |
}; | |
})( jQuery );/* | |
* jQuery Mobile Framework : "navbar" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.navbar", $.mobile.widget, { | |
options: { | |
iconpos: "top", | |
grid: null, | |
initSelector: ":jqmData(role='navbar')" | |
}, | |
_create: function(){ | |
var $navbar = this.element, | |
$navbtns = $navbar.find( "a" ), | |
iconpos = $navbtns.filter( ":jqmData(icon)" ).length ? | |
this.options.iconpos : undefined; | |
$navbar.addClass( "ui-navbar" ) | |
.attr( "role","navigation" ) | |
.find( "ul" ) | |
.grid({ grid: this.options.grid }); | |
if ( !iconpos ) { | |
$navbar.addClass( "ui-navbar-noicons" ); | |
} | |
$navbtns.buttonMarkup({ | |
corners: false, | |
shadow: false, | |
iconpos: iconpos | |
}); | |
$navbar.delegate( "a", "vclick", function( event ) { | |
$navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass ); | |
$( this ).addClass( $.mobile.activeBtnClass ); | |
}); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.navbar.prototype.options.initSelector, e.target ).navbar(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "listview" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
//Keeps track of the number of lists per page UID | |
//This allows support for multiple nested list in the same page | |
//https://github.com/jquery/jquery-mobile/issues/1617 | |
var listCountPerPage = {}; | |
$.widget( "mobile.listview", $.mobile.widget, { | |
options: { | |
theme: "c", | |
countTheme: "c", | |
headerTheme: "b", | |
dividerTheme: "b", | |
splitIcon: "arrow-r", | |
splitTheme: "b", | |
inset: false, | |
initSelector: ":jqmData(role='listview')" | |
}, | |
_create: function() { | |
var t = this; | |
// create listview markup | |
t.element.addClass(function( i, orig ) { | |
return orig + " ui-listview " + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" ); | |
}); | |
t.refresh(); | |
}, | |
_itemApply: function( $list, item ) { | |
// TODO class has to be defined in markup | |
item.find( ".ui-li-count" ) | |
.addClass( "ui-btn-up-" + ( $list.jqmData( "counttheme" ) || this.options.countTheme ) + " ui-btn-corner-all" ).end() | |
.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ).end() | |
.find( "p, dl" ).addClass( "ui-li-desc" ).end() | |
.find( ">img:eq(0), .ui-link-inherit>img:eq(0)" ).addClass( "ui-li-thumb" ).each(function() { | |
item.addClass( $(this).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" ); | |
}).end() | |
.find( ".ui-li-aside" ).each(function() { | |
var $this = $(this); | |
$this.prependTo( $this.parent() ); //shift aside to front for css float | |
}); | |
}, | |
_removeCorners: function( li, which ) { | |
var top = "ui-corner-top ui-corner-tr ui-corner-tl", | |
bot = "ui-corner-bottom ui-corner-br ui-corner-bl"; | |
li = li.add( li.find( ".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb" ) ); | |
if ( which === "top" ) { | |
li.removeClass( top ); | |
} else if ( which === "bottom" ) { | |
li.removeClass( bot ); | |
} else { | |
li.removeClass( top + " " + bot ); | |
} | |
}, | |
refresh: function( create ) { | |
this.parentPage = this.element.closest( ".ui-page" ); | |
this._createSubPages(); | |
var o = this.options, | |
$list = this.element, | |
self = this, | |
dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme, | |
listsplittheme = $list.jqmData( "splittheme" ), | |
listspliticon = $list.jqmData( "spliticon" ), | |
li = $list.children( "li" ), | |
counter = $.support.cssPseudoElement || !$.nodeName( $list[ 0 ], "ol" ) ? 0 : 1, | |
item, itemClass, itemTheme, | |
a, last, splittheme, countParent, icon; | |
if ( counter ) { | |
$list.find( ".ui-li-dec" ).remove(); | |
} | |
for ( var pos = 0, numli = li.length; pos < numli; pos++ ) { | |
item = li.eq( pos ); | |
itemClass = "ui-li"; | |
// If we're creating the element, we update it regardless | |
if ( create || !item.hasClass( "ui-li" ) ) { | |
itemTheme = item.jqmData("theme") || o.theme; | |
a = item.children( "a" ); | |
if ( a.length ) { | |
icon = item.jqmData("icon"); | |
item.buttonMarkup({ | |
wrapperEls: "div", | |
shadow: false, | |
corners: false, | |
iconpos: "right", | |
icon: a.length > 1 || icon === false ? false : icon || "arrow-r", | |
theme: itemTheme | |
}); | |
a.first().addClass( "ui-link-inherit" ); | |
if ( a.length > 1 ) { | |
itemClass += " ui-li-has-alt"; | |
last = a.last(); | |
splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme; | |
last.appendTo(item) | |
.attr( "title", last.text() ) | |
.addClass( "ui-li-link-alt" ) | |
.empty() | |
.buttonMarkup({ | |
shadow: false, | |
corners: false, | |
theme: itemTheme, | |
icon: false, | |
iconpos: false | |
}) | |
.find( ".ui-btn-inner" ) | |
.append( | |
$( "<span />" ).buttonMarkup({ | |
shadow: true, | |
corners: true, | |
theme: splittheme, | |
iconpos: "notext", | |
icon: listspliticon || last.jqmData( "icon" ) || o.splitIcon | |
}) | |
); | |
} | |
} else if ( item.jqmData( "role" ) === "list-divider" ) { | |
itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme; | |
item.attr( "role", "heading" ); | |
//reset counter when a divider heading is encountered | |
if ( counter ) { | |
counter = 1; | |
} | |
} else { | |
itemClass += " ui-li-static ui-body-" + itemTheme; | |
} | |
} | |
if ( o.inset ) { | |
if ( pos === 0 ) { | |
itemClass += " ui-corner-top"; | |
item.add( item.find( ".ui-btn-inner" ) ) | |
.find( ".ui-li-link-alt" ) | |
.addClass( "ui-corner-tr" ) | |
.end() | |
.find( ".ui-li-thumb" ) | |
.addClass( "ui-corner-tl" ); | |
if ( item.next().next().length ) { | |
self._removeCorners( item.next() ); | |
} | |
} | |
if ( pos === li.length - 1 ) { | |
itemClass += " ui-corner-bottom"; | |
item.add( item.find( ".ui-btn-inner" ) ) | |
.find( ".ui-li-link-alt" ) | |
.addClass( "ui-corner-br" ) | |
.end() | |
.find( ".ui-li-thumb" ) | |
.addClass( "ui-corner-bl" ); | |
if ( item.prev().prev().length ) { | |
self._removeCorners( item.prev() ); | |
} else if ( item.prev().length ) { | |
self._removeCorners( item.prev(), "bottom" ); | |
} | |
} | |
} | |
if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) { | |
countParent = item.is( ".ui-li-static:first" ) ? item : item.find( ".ui-link-inherit" ); | |
countParent.addClass( "ui-li-jsnumbering" ) | |
.prepend( "<span class='ui-li-dec'>" + (counter++) + ". </span>" ); | |
} | |
item.add( item.children( ".ui-btn-inner" ) ).addClass( itemClass ); | |
if ( !create ) { | |
self._itemApply( $list, item ); | |
} | |
} | |
}, | |
//create a string for ID/subpage url creation | |
_idStringEscape: function( str ) { | |
return str.replace(/[^a-zA-Z0-9]/g, '-'); | |
}, | |
_createSubPages: function() { | |
var parentList = this.element, | |
parentPage = parentList.closest( ".ui-page" ), | |
parentUrl = parentPage.jqmData( "url" ), | |
parentId = parentUrl || parentPage[ 0 ][ $.expando ], | |
parentListId = parentList.attr( "id" ), | |
o = this.options, | |
dns = "data-" + $.mobile.ns, | |
self = this, | |
persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ), | |
hasSubPages; | |
if ( typeof listCountPerPage[ parentId ] === "undefined" ) { | |
listCountPerPage[ parentId ] = -1; | |
} | |
parentListId = parentListId || ++listCountPerPage[ parentId ]; | |
$( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) { | |
var self = this, | |
list = $( this ), | |
listId = list.attr( "id" ) || parentListId + "-" + i, | |
parent = list.parent(), | |
nodeEls = $( list.prevAll().toArray().reverse() ), | |
nodeEls = nodeEls.length ? nodeEls : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" ), | |
title = nodeEls.first().text(),//url limits to first 30 chars of text | |
id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId, | |
theme = list.jqmData( "theme" ) || o.theme, | |
countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme, | |
newPage, anchor; | |
//define hasSubPages for use in later removal | |
hasSubPages = true; | |
newPage = list.detach() | |
.wrap( "<div " + dns + "role='page' " + dns + "url='" + id + "' " + dns + "theme='" + theme + "' " + dns + "count-theme='" + countTheme + "'><div " + dns + "role='content'></div></div>" ) | |
.parent() | |
.before( "<div " + dns + "role='header' " + dns + "theme='" + o.headerTheme + "'><div class='ui-title'>" + title + "</div></div>" ) | |
.after( persistentFooterID ? $( "<div " + dns + "role='footer' " + dns + "id='"+ persistentFooterID +"'>") : "" ) | |
.parent() | |
.appendTo( $.mobile.pageContainer ); | |
newPage.page(); | |
anchor = parent.find('a:first'); | |
if ( !anchor.length ) { | |
anchor = $( "<a/>" ).html( nodeEls || title ).prependTo( parent.empty() ); | |
} | |
anchor.attr( "href", "#" + id ); | |
}).listview(); | |
//on pagehide, remove any nested pages along with the parent page, as long as they aren't active | |
if( hasSubPages && parentPage.data("page").options.domCache === false ){ | |
var newRemove = function( e, ui ){ | |
var nextPage = ui.nextPage, npURL; | |
if( ui.nextPage ){ | |
npURL = nextPage.jqmData( "url" ); | |
if( npURL.indexOf( parentUrl + "&" + $.mobile.subPageUrlKey ) !== 0 ){ | |
self.childPages().remove(); | |
parentPage.remove(); | |
} | |
} | |
}; | |
// unbind the original page remove and replace with our specialized version | |
parentPage | |
.unbind( "pagehide.remove" ) | |
.bind( "pagehide.remove", newRemove); | |
} | |
}, | |
// TODO sort out a better way to track sub pages of the listview this is brittle | |
childPages: function(){ | |
var parentUrl = this.parentPage.jqmData( "url" ); | |
return $( ":jqmData(url^='"+ parentUrl + "&" + $.mobile.subPageUrlKey +"')"); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.listview.prototype.options.initSelector, e.target ).listview(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "listview" filter extension | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.mobile.listview.prototype.options.filter = false; | |
$.mobile.listview.prototype.options.filterPlaceholder = "Filter items..."; | |
$.mobile.listview.prototype.options.filterTheme = "c"; | |
$( ":jqmData(role='listview')" ).live( "listviewcreate", function() { | |
var list = $( this ), | |
listview = list.data( "listview" ); | |
if ( !listview.options.filter ) { | |
return; | |
} | |
var wrapper = $( "<form>", { | |
"class": "ui-listview-filter ui-bar-" + listview.options.filterTheme, | |
"role": "search" | |
}), | |
search = $( "<input>", { | |
placeholder: listview.options.filterPlaceholder | |
}) | |
.attr( "data-" + $.mobile.ns + "type", "search" ) | |
.jqmData( "lastval", "" ) | |
.bind( "keyup change", function() { | |
var $this = $(this), | |
val = this.value.toLowerCase(), | |
listItems = null, | |
lastval = $this.jqmData( "lastval" ) + "", | |
childItems = false, | |
itemtext = "", | |
item; | |
// Change val as lastval for next execution | |
$this.jqmData( "lastval" , val ); | |
change = val.replace( new RegExp( "^" + lastval ) , "" ); | |
if ( val.length < lastval.length || change.length != ( val.length - lastval.length ) ) { | |
// Removed chars or pasted something totaly different, check all items | |
listItems = list.children(); | |
} else { | |
// Only chars added, not removed, only use visible subset | |
listItems = list.children( ":not(.ui-screen-hidden)" ); | |
} | |
if ( val ) { | |
// This handles hiding regular rows without the text we search for | |
// and any list dividers without regular rows shown under it | |
for ( var i = listItems.length - 1; i >= 0; i-- ) { | |
item = $( listItems[ i ] ); | |
itemtext = item.jqmData( "filtertext" ) || item.text(); | |
if ( item.is( "li:jqmData(role=list-divider)" ) ) { | |
item.toggleClass( "ui-filter-hidequeue" , !childItems ); | |
// New bucket! | |
childItems = false; | |
} else if ( itemtext.toLowerCase().indexOf( val ) === -1 ) { | |
//mark to be hidden | |
item.toggleClass( "ui-filter-hidequeue" , true ); | |
} else { | |
// There"s a shown item in the bucket | |
childItems = true; | |
} | |
} | |
// Show items, not marked to be hidden | |
listItems | |
.filter( ":not(.ui-filter-hidequeue)" ) | |
.toggleClass( "ui-screen-hidden", false ); | |
// Hide items, marked to be hidden | |
listItems | |
.filter( ".ui-filter-hidequeue" ) | |
.toggleClass( "ui-screen-hidden", true ) | |
.toggleClass( "ui-filter-hidequeue", false ); | |
} else { | |
//filtervalue is empty => show all | |
listItems.toggleClass( "ui-screen-hidden", false ); | |
} | |
}) | |
.appendTo( wrapper ) | |
.textinput(); | |
if ( $( this ).jqmData( "inset" ) ) { | |
wrapper.addClass( "ui-listview-filter-inset" ); | |
} | |
wrapper.bind( "submit", function() { | |
return false; | |
}) | |
.insertBefore( list ); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "fieldcontain" plugin - simple class additions to make form row separators | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='nojs')", e.target ).addClass( "ui-nojs" ); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "checkboxradio" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.checkboxradio", $.mobile.widget, { | |
options: { | |
theme: null, | |
initSelector: "input[type='checkbox'],input[type='radio']" | |
}, | |
_create: function() { | |
var self = this, | |
input = this.element, | |
// NOTE: Windows Phone could not find the label through a selector | |
// filter works though. | |
label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label" ).filter( "[for='" + input[ 0 ].id + "']"), | |
inputtype = input.attr( "type" ), | |
checkedState = inputtype + "-on", | |
uncheckedState = inputtype + "-off", | |
icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState, | |
activeBtn = icon ? "" : " " + $.mobile.activeBtnClass, | |
checkedClass = "ui-" + checkedState + activeBtn, | |
uncheckedClass = "ui-" + uncheckedState, | |
checkedicon = "ui-icon-" + checkedState, | |
uncheckedicon = "ui-icon-" + uncheckedState; | |
if ( inputtype !== "checkbox" && inputtype !== "radio" ) { | |
return; | |
} | |
// Expose for other methods | |
$.extend( this, { | |
label: label, | |
inputtype: inputtype, | |
checkedClass: checkedClass, | |
uncheckedClass: uncheckedClass, | |
checkedicon: checkedicon, | |
uncheckedicon: uncheckedicon | |
}); | |
// If there's no selected theme... | |
if( !this.options.theme ) { | |
this.options.theme = this.element.jqmData( "theme" ); | |
} | |
label.buttonMarkup({ | |
theme: this.options.theme, | |
icon: icon, | |
shadow: false | |
}); | |
// Wrap the input + label in a div | |
input.add( label ) | |
.wrapAll( "<div class='ui-" + inputtype + "'></div>" ); | |
label.bind({ | |
vmouseover: function() { | |
if ( $( this ).parent().is( ".ui-disabled" ) ) { | |
return false; | |
} | |
}, | |
vclick: function( event ) { | |
if ( input.is( ":disabled" ) ) { | |
event.preventDefault(); | |
return; | |
} | |
self._cacheVals(); | |
input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) ); | |
// Input set for common radio buttons will contain all the radio | |
// buttons, but will not for checkboxes. clearing the checked status | |
// of other radios ensures the active button state is applied properly | |
self._getInputSet().not( input ).prop( "checked", false ); | |
self._updateAll(); | |
return false; | |
} | |
}); | |
input | |
.bind({ | |
vmousedown: function() { | |
this._cacheVals(); | |
}, | |
vclick: function() { | |
var $this = $(this); | |
// Adds checked attribute to checked input when keyboard is used | |
if ( $this.is( ":checked" ) ) { | |
$this.prop( "checked", true); | |
self._getInputSet().not($this).prop( "checked", false ); | |
} else { | |
$this.prop( "checked", false ); | |
} | |
self._updateAll(); | |
}, | |
focus: function() { | |
label.addClass( "ui-focus" ); | |
}, | |
blur: function() { | |
label.removeClass( "ui-focus" ); | |
} | |
}); | |
this.refresh(); | |
}, | |
_cacheVals: function() { | |
this._getInputSet().each(function() { | |
var $this = $(this); | |
$this.jqmData( "cacheVal", $this.is( ":checked" ) ); | |
}); | |
}, | |
//returns either a set of radios with the same name attribute, or a single checkbox | |
_getInputSet: function(){ | |
if(this.inputtype == "checkbox") { | |
return this.element; | |
} | |
return this.element.closest( "form,fieldset,:jqmData(role='page')" ) | |
.find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" ); | |
}, | |
_updateAll: function() { | |
var self = this; | |
this._getInputSet().each(function() { | |
var $this = $(this); | |
if ( $this.is( ":checked" ) || self.inputtype === "checkbox" ) { | |
$this.trigger( "change" ); | |
} | |
}) | |
.checkboxradio( "refresh" ); | |
}, | |
refresh: function() { | |
var input = this.element, | |
label = this.label, | |
icon = label.find( ".ui-icon" ); | |
// input[0].checked expando doesn't always report the proper value | |
// for checked='checked' | |
if ( $( input[ 0 ] ).prop( "checked" ) ) { | |
label.addClass( this.checkedClass ).removeClass( this.uncheckedClass ); | |
icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon ); | |
} else { | |
label.removeClass( this.checkedClass ).addClass( this.uncheckedClass ); | |
icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon ); | |
} | |
if ( input.is( ":disabled" ) ) { | |
this.disable(); | |
} else { | |
this.enable(); | |
} | |
}, | |
disable: function() { | |
this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" ); | |
}, | |
enable: function() { | |
this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.checkboxradio.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.checkboxradio(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "button" plugin - links that proxy to native input/buttons | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.button", $.mobile.widget, { | |
options: { | |
theme: null, | |
icon: null, | |
iconpos: null, | |
inline: null, | |
corners: true, | |
shadow: true, | |
iconshadow: true, | |
initSelector: "button, [type='button'], [type='submit'], [type='reset'], [type='image']" | |
}, | |
_create: function() { | |
var $el = this.element, | |
o = this.options, | |
type; | |
// Add ARIA role | |
this.button = $( "<div></div>" ) | |
.text( $el.text() || $el.val() ) | |
.buttonMarkup({ | |
theme: o.theme, | |
icon: o.icon, | |
iconpos: o.iconpos, | |
inline: o.inline, | |
corners: o.corners, | |
shadow: o.shadow, | |
iconshadow: o.iconshadow | |
}) | |
.insertBefore( $el ) | |
.append( $el.addClass( "ui-btn-hidden" ) ); | |
// Add hidden input during submit | |
type = $el.attr( "type" ); | |
if ( type !== "button" && type !== "reset" ) { | |
$el.bind( "vclick", function() { | |
var $buttonPlaceholder = $( "<input>", { | |
type: "hidden", | |
name: $el.attr( "name" ), | |
value: $el.attr( "value" ) | |
}) | |
.insertBefore( $el ); | |
// Bind to doc to remove after submit handling | |
$( document ).submit(function(){ | |
$buttonPlaceholder.remove(); | |
}); | |
}); | |
} | |
this.refresh(); | |
}, | |
enable: function() { | |
this.element.attr( "disabled", false ); | |
this.button.removeClass( "ui-disabled" ).attr( "aria-disabled", false ); | |
return this._setOption( "disabled", false ); | |
}, | |
disable: function() { | |
this.element.attr( "disabled", true ); | |
this.button.addClass( "ui-disabled" ).attr( "aria-disabled", true ); | |
return this._setOption( "disabled", true ); | |
}, | |
refresh: function() { | |
if ( this.element.attr( "disabled" ) ) { | |
this.disable(); | |
} else { | |
this.enable(); | |
} | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.button.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.button(); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "slider" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, undefined ) { | |
$.widget( "mobile.slider", $.mobile.widget, { | |
options: { | |
theme: null, | |
trackTheme: null, | |
disabled: false, | |
initSelector: "input[type='range'], :jqmData(type='range'), :jqmData(role='slider')" | |
}, | |
_create: function() { | |
// TODO: Each of these should have comments explain what they're for | |
var self = this, | |
control = this.element, | |
parentTheme = control.parents( "[class*='ui-bar-'],[class*='ui-body-']" ).eq( 0 ), | |
parentTheme = parentTheme.length ? parentTheme.attr( "class" ).match( /ui-(bar|body)-([a-z])/ )[ 2 ] : "c", | |
theme = this.options.theme ? this.options.theme : parentTheme, | |
trackTheme = this.options.trackTheme ? this.options.trackTheme : parentTheme, | |
cType = control[ 0 ].nodeName.toLowerCase(), | |
selectClass = ( cType == "select" ) ? "ui-slider-switch" : "", | |
controlID = control.attr( "id" ), | |
labelID = controlID + "-label", | |
label = $( "[for='"+ controlID +"']" ).attr( "id", labelID ), | |
val = function() { | |
return cType == "input" ? parseFloat( control.val() ) : control[0].selectedIndex; | |
}, | |
min = cType == "input" ? parseFloat( control.attr( "min" ) ) : 0, | |
max = cType == "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length-1, | |
step = window.parseFloat( control.attr( "step" ) || 1 ), | |
slider = $( "<div class='ui-slider " + selectClass + " ui-btn-down-" + trackTheme + | |
" ui-btn-corner-all' role='application'></div>" ), | |
handle = $( "<a href='#' class='ui-slider-handle'></a>" ) | |
.appendTo( slider ) | |
.buttonMarkup({ corners: true, theme: theme, shadow: true }) | |
.attr({ | |
"role": "slider", | |
"aria-valuemin": min, | |
"aria-valuemax": max, | |
"aria-valuenow": val(), | |
"aria-valuetext": val(), | |
"title": val(), | |
"aria-labelledby": labelID | |
}), | |
options; | |
$.extend( this, { | |
slider: slider, | |
handle: handle, | |
dragging: false, | |
beforeStart: null | |
}); | |
if ( cType == "select" ) { | |
slider.wrapInner( "<div class='ui-slider-inneroffset'></div>" ); | |
options = control.find( "option" ); | |
control.find( "option" ).each(function( i ) { | |
var side = !i ? "b":"a", | |
corners = !i ? "right" :"left", | |
theme = !i ? " ui-btn-down-" + trackTheme :" ui-btn-active"; | |
$( "<div class='ui-slider-labelbg ui-slider-labelbg-" + side + theme + " ui-btn-corner-" + corners + "'></div>" ) | |
.prependTo( slider ); | |
$( "<span class='ui-slider-label ui-slider-label-" + side + theme + " ui-btn-corner-" + corners + "' role='img'>" + $( this ).text() + "</span>" ) | |
.prependTo( handle ); | |
}); | |
} | |
label.addClass( "ui-slider" ); | |
// monitor the input for updated values | |
control.addClass( cType === "input" ? "ui-slider-input" : "ui-slider-switch" ) | |
.change( function() { | |
self.refresh( val(), true ); | |
}) | |
.keyup( function() { // necessary? | |
self.refresh( val(), true, true ); | |
}) | |
.blur( function() { | |
self.refresh( val(), true ); | |
}); | |
// prevent screen drag when slider activated | |
$( document ).bind( "vmousemove", function( event ) { | |
if ( self.dragging ) { | |
self.refresh( event ); | |
return false; | |
} | |
}); | |
slider.bind( "vmousedown", function( event ) { | |
self.dragging = true; | |
if ( cType === "select" ) { | |
self.beforeStart = control[0].selectedIndex; | |
} | |
self.refresh( event ); | |
return false; | |
}); | |
slider.add( document ) | |
.bind( "vmouseup", function() { | |
if ( self.dragging ) { | |
self.dragging = false; | |
if ( cType === "select" ) { | |
if ( self.beforeStart === control[ 0 ].selectedIndex ) { | |
//tap occurred, but value didn't change. flip it! | |
self.refresh( !self.beforeStart ? 1 : 0 ); | |
} | |
var curval = val(); | |
var snapped = Math.round( curval / ( max - min ) * 100 ); | |
handle | |
.addClass( "ui-slider-handle-snapping" ) | |
.css( "left", snapped + "%" ) | |
.animationComplete( function() { | |
handle.removeClass( "ui-slider-handle-snapping" ); | |
}); | |
} | |
return false; | |
} | |
}); | |
slider.insertAfter( control ); | |
// NOTE force focus on handle | |
this.handle | |
.bind( "vmousedown", function() { | |
$( this ).focus(); | |
}) | |
.bind( "vclick", false ); | |
this.handle | |
.bind( "keydown", function( event ) { | |
var index = val(); | |
if ( self.options.disabled ) { | |
return; | |
} | |
// In all cases prevent the default and mark the handle as active | |
switch ( event.keyCode ) { | |
case $.mobile.keyCode.HOME: | |
case $.mobile.keyCode.END: | |
case $.mobile.keyCode.PAGE_UP: | |
case $.mobile.keyCode.PAGE_DOWN: | |
case $.mobile.keyCode.UP: | |
case $.mobile.keyCode.RIGHT: | |
case $.mobile.keyCode.DOWN: | |
case $.mobile.keyCode.LEFT: | |
event.preventDefault(); | |
if ( !self._keySliding ) { | |
self._keySliding = true; | |
$( this ).addClass( "ui-state-active" ); | |
} | |
break; | |
} | |
// move the slider according to the keypress | |
switch ( event.keyCode ) { | |
case $.mobile.keyCode.HOME: | |
self.refresh( min ); | |
break; | |
case $.mobile.keyCode.END: | |
self.refresh( max ); | |
break; | |
case $.mobile.keyCode.PAGE_UP: | |
case $.mobile.keyCode.UP: | |
case $.mobile.keyCode.RIGHT: | |
self.refresh( index + step ); | |
break; | |
case $.mobile.keyCode.PAGE_DOWN: | |
case $.mobile.keyCode.DOWN: | |
case $.mobile.keyCode.LEFT: | |
self.refresh( index - step ); | |
break; | |
} | |
}) // remove active mark | |
.keyup( function( event ) { | |
if ( self._keySliding ) { | |
self._keySliding = false; | |
$( this ).removeClass( "ui-state-active" ); | |
} | |
}); | |
this.refresh(undefined, undefined, true); | |
}, | |
refresh: function( val, isfromControl, preventInputUpdate ) { | |
if ( this.options.disabled ) { return; } | |
var control = this.element, percent, | |
cType = control[0].nodeName.toLowerCase(), | |
min = cType === "input" ? parseFloat( control.attr( "min" ) ) : 0, | |
max = cType === "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length - 1; | |
if ( typeof val === "object" ) { | |
var data = val, | |
// a slight tolerance helped get to the ends of the slider | |
tol = 8; | |
if ( !this.dragging || | |
data.pageX < this.slider.offset().left - tol || | |
data.pageX > this.slider.offset().left + this.slider.width() + tol ) { | |
return; | |
} | |
percent = Math.round( ( ( data.pageX - this.slider.offset().left ) / this.slider.width() ) * 100 ); | |
} else { | |
if ( val == null ) { | |
val = cType === "input" ? parseFloat( control.val() ) : control[0].selectedIndex; | |
} | |
percent = ( parseFloat( val ) - min ) / ( max - min ) * 100; | |
} | |
if ( isNaN( percent ) ) { | |
return; | |
} | |
if ( percent < 0 ) { | |
percent = 0; | |
} | |
if ( percent > 100 ) { | |
percent = 100; | |
} | |
var newval = Math.round( ( percent / 100 ) * ( max - min ) ) + min; | |
if ( newval < min ) { | |
newval = min; | |
} | |
if ( newval > max ) { | |
newval = max; | |
} | |
// Flip the stack of the bg colors | |
if ( percent > 60 && cType === "select" ) { | |
// TODO: Dead path? | |
} | |
this.handle.css( "left", percent + "%" ); | |
this.handle.attr( { | |
"aria-valuenow": cType === "input" ? newval : control.find( "option" ).eq( newval ).attr( "value" ), | |
"aria-valuetext": cType === "input" ? newval : control.find( "option" ).eq( newval ).text(), | |
title: newval | |
}); | |
// add/remove classes for flip toggle switch | |
if ( cType === "select" ) { | |
if ( newval === 0 ) { | |
this.slider.addClass( "ui-slider-switch-a" ) | |
.removeClass( "ui-slider-switch-b" ); | |
} else { | |
this.slider.addClass( "ui-slider-switch-b" ) | |
.removeClass( "ui-slider-switch-a" ); | |
} | |
} | |
if ( !preventInputUpdate ) { | |
// update control"s value | |
if ( cType === "input" ) { | |
control.val( newval ); | |
} else { | |
control[ 0 ].selectedIndex = newval; | |
} | |
if ( !isfromControl ) { | |
control.trigger( "change" ); | |
} | |
} | |
}, | |
enable: function() { | |
this.element.attr( "disabled", false ); | |
this.slider.removeClass( "ui-disabled" ).attr( "aria-disabled", false ); | |
return this._setOption( "disabled", false ); | |
}, | |
disable: function() { | |
this.element.attr( "disabled", true ); | |
this.slider.addClass( "ui-disabled" ).attr( "aria-disabled", true ); | |
return this._setOption( "disabled", true ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.slider.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.slider(); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.textinput", $.mobile.widget, { | |
options: { | |
theme: null, | |
initSelector: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea" | |
}, | |
_create: function() { | |
var input = this.element, | |
o = this.options, | |
theme = o.theme, | |
themedParent, themeclass, themeLetter, focusedEl, clearbtn; | |
if ( !theme ) { | |
themedParent = this.element.closest( "[class*='ui-bar-'],[class*='ui-body-']" ); | |
themeLetter = themedParent.length && /ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) ); | |
theme = themeLetter && themeLetter[2] || "c"; | |
} | |
themeclass = " ui-body-" + theme; | |
$( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" ); | |
input.addClass("ui-input-text ui-body-"+ o.theme ); | |
focusedEl = input; | |
// XXX: Temporary workaround for issue 785. Turn off autocorrect and | |
// autocomplete since the popup they use can't be dismissed by | |
// the user. Note that we test for the presence of the feature | |
// by looking for the autocorrect property on the input element. | |
if ( typeof input[0].autocorrect !== "undefined" ) { | |
// Set the attribute instead of the property just in case there | |
// is code that attempts to make modifications via HTML. | |
input[0].setAttribute( "autocorrect", "off" ); | |
input[0].setAttribute( "autocomplete", "off" ); | |
} | |
//"search" input widget | |
if ( input.is( "[type='search'],:jqmData(type='search')" ) ) { | |
focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield" + themeclass + "'></div>" ).parent(); | |
clearbtn = $( "<a href='#' class='ui-input-clear' title='clear text'>clear text</a>" ) | |
.tap(function( event ) { | |
input.val( "" ).focus(); | |
input.trigger( "change" ); | |
clearbtn.addClass( "ui-input-clear-hidden" ); | |
event.preventDefault(); | |
}) | |
.appendTo( focusedEl ) | |
.buttonMarkup({ | |
icon: "delete", | |
iconpos: "notext", | |
corners: true, | |
shadow: true | |
}); | |
function toggleClear() { | |
if ( !input.val() ) { | |
clearbtn.addClass( "ui-input-clear-hidden" ); | |
} else { | |
clearbtn.removeClass( "ui-input-clear-hidden" ); | |
} | |
} | |
toggleClear(); | |
input.keyup( toggleClear ) | |
.focus( toggleClear ); | |
} else { | |
input.addClass( "ui-corner-all ui-shadow-inset" + themeclass ); | |
} | |
input.focus(function() { | |
focusedEl.addClass( "ui-focus" ); | |
}) | |
.blur(function(){ | |
focusedEl.removeClass( "ui-focus" ); | |
}); | |
// Autogrow | |
if ( input.is( "textarea" ) ) { | |
var extraLineHeight = 15, | |
keyupTimeoutBuffer = 100, | |
keyup = function() { | |
var scrollHeight = input[ 0 ].scrollHeight, | |
clientHeight = input[ 0 ].clientHeight; | |
if ( clientHeight < scrollHeight ) { | |
input.css({ | |
height: (scrollHeight + extraLineHeight) | |
}); | |
} | |
}, | |
keyupTimeout; | |
input.keyup(function() { | |
clearTimeout( keyupTimeout ); | |
keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer ); | |
}); | |
} | |
}, | |
disable: function(){ | |
( this.element.attr( "disabled", true ).is( "[type='search'],:jqmData(type='search')" ) ? | |
this.element.parent() : this.element ).addClass( "ui-disabled" ); | |
}, | |
enable: function(){ | |
( this.element.attr( "disabled", false).is( "[type='search'],:jqmData(type='search')" ) ? | |
this.element.parent() : this.element ).removeClass( "ui-disabled" ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.textinput.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.textinput(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "selectmenu" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.selectmenu", $.mobile.widget, { | |
options: { | |
theme: null, | |
disabled: false, | |
icon: "arrow-d", | |
iconpos: "right", | |
inline: null, | |
corners: true, | |
shadow: true, | |
iconshadow: true, | |
menuPageTheme: "b", | |
overlayTheme: "a", | |
hidePlaceholderMenuItems: true, | |
closeText: "Close", | |
nativeMenu: true, | |
initSelector: "select:not(:jqmData(role='slider'))" | |
}, | |
_create: function() { | |
var self = this, | |
o = this.options, | |
select = this.element | |
.wrap( "<div class='ui-select'>" ), | |
selectID = select.attr( "id" ), | |
label = $( "label[for='"+ selectID +"']" ).addClass( "ui-select" ), | |
// IE throws an exception at options.item() function when | |
// there is no selected item | |
// select first in this case | |
selectedIndex = select[ 0 ].selectedIndex == -1 ? 0 : select[ 0 ].selectedIndex, | |
button = ( self.options.nativeMenu ? $( "<div/>" ) : $( "<a>", { | |
"href": "#", | |
"role": "button", | |
"id": buttonId, | |
"aria-haspopup": "true", | |
"aria-owns": menuId | |
}) ) | |
.text( $( select[ 0 ].options.item( selectedIndex ) ).text() ) | |
.insertBefore( select ) | |
.buttonMarkup({ | |
theme: o.theme, | |
icon: o.icon, | |
iconpos: o.iconpos, | |
inline: o.inline, | |
corners: o.corners, | |
shadow: o.shadow, | |
iconshadow: o.iconshadow | |
}), | |
// Multi select or not | |
isMultiple = self.isMultiple = select[ 0 ].multiple; | |
// Opera does not properly support opacity on select elements | |
// In Mini, it hides the element, but not its text | |
// On the desktop,it seems to do the opposite | |
// for these reasons, using the nativeMenu option results in a full native select in Opera | |
if ( o.nativeMenu && window.opera && window.opera.version ) { | |
select.addClass( "ui-select-nativeonly" ); | |
} | |
//vars for non-native menus | |
if ( !o.nativeMenu ) { | |
var options = select.find("option"), | |
buttonId = selectID + "-button", | |
menuId = selectID + "-menu", | |
thisPage = select.closest( ".ui-page" ), | |
//button theme | |
theme = /ui-btn-up-([a-z])/.exec( button.attr( "class" ) )[1], | |
menuPage = $( "<div data-" + $.mobile.ns + "role='dialog' data-" +$.mobile.ns + "theme='"+ o.menuPageTheme +"'>" + | |
"<div data-" + $.mobile.ns + "role='header'>" + | |
"<div class='ui-title'>" + label.text() + "</div>"+ | |
"</div>"+ | |
"<div data-" + $.mobile.ns + "role='content'></div>"+ | |
"</div>" ) | |
.appendTo( $.mobile.pageContainer ) | |
.page(), | |
menuPageContent = menuPage.find( ".ui-content" ), | |
menuPageClose = menuPage.find( ".ui-header a" ), | |
screen = $( "<div>", {"class": "ui-selectmenu-screen ui-screen-hidden"}) | |
.appendTo( thisPage ), | |
listbox = $("<div>", { "class": "ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-" + o.overlayTheme + " " + $.mobile.defaultDialogTransition }) | |
.insertAfter(screen), | |
list = $( "<ul>", { | |
"class": "ui-selectmenu-list", | |
"id": menuId, | |
"role": "listbox", | |
"aria-labelledby": buttonId | |
}) | |
.attr( "data-" + $.mobile.ns + "theme", theme ) | |
.appendTo( listbox ), | |
header = $( "<div>", { | |
"class": "ui-header ui-bar-" + theme | |
}) | |
.prependTo( listbox ), | |
headerTitle = $( "<h1>", { | |
"class": "ui-title" | |
}) | |
.appendTo( header ), | |
headerClose = $( "<a>", { | |
"text": o.closeText, | |
"href": "#", | |
"class": "ui-btn-left" | |
}) | |
.attr( "data-" + $.mobile.ns + "iconpos", "notext" ) | |
.attr( "data-" + $.mobile.ns + "icon", "delete" ) | |
.appendTo( header ) | |
.buttonMarkup(), | |
menuType; | |
} // End non native vars | |
// Add counter for multi selects | |
if ( isMultiple ) { | |
self.buttonCount = $( "<span>" ) | |
.addClass( "ui-li-count ui-btn-up-c ui-btn-corner-all" ) | |
.hide() | |
.appendTo( button ); | |
} | |
// Disable if specified | |
if ( o.disabled ) { | |
this.disable(); | |
} | |
// Events on native select | |
select.change(function() { | |
self.refresh(); | |
}); | |
// Expose to other methods | |
$.extend( self, { | |
select: select, | |
optionElems: options, | |
selectID: selectID, | |
label: label, | |
buttonId: buttonId, | |
menuId: menuId, | |
thisPage: thisPage, | |
button: button, | |
menuPage: menuPage, | |
menuPageContent: menuPageContent, | |
screen: screen, | |
listbox: listbox, | |
list: list, | |
menuType: menuType, | |
header: header, | |
headerClose: headerClose, | |
headerTitle: headerTitle, | |
placeholder: "" | |
}); | |
// Support for using the native select menu with a custom button | |
if ( o.nativeMenu ) { | |
select.appendTo( button ) | |
.bind( "vmousedown", function() { | |
// Add active class to button | |
button.addClass( $.mobile.activeBtnClass ); | |
}) | |
.bind( "focus vmouseover", function() { | |
button.trigger( "vmouseover" ); | |
}) | |
.bind( "vmousemove", function() { | |
// Remove active class on scroll/touchmove | |
button.removeClass( $.mobile.activeBtnClass ); | |
}) | |
.bind( "change blur vmouseout", function() { | |
button.trigger( "vmouseout" ) | |
.removeClass( $.mobile.activeBtnClass ); | |
}); | |
} else { | |
// Create list from select, update state | |
self.refresh(); | |
select.attr( "tabindex", "-1" ) | |
.focus(function() { | |
$(this).blur(); | |
button.focus(); | |
}); | |
// Button events | |
button.bind( "vclick keydown" , function( event ) { | |
if ( event.type == "vclick" || | |
event.keyCode && ( event.keyCode === $.mobile.keyCode.ENTER || | |
event.keyCode === $.mobile.keyCode.SPACE ) ) { | |
self.open(); | |
event.preventDefault(); | |
} | |
}); | |
// Events for list items | |
list.attr( "role", "listbox" ) | |
.delegate( ".ui-li>a", "focusin", function() { | |
$( this ).attr( "tabindex", "0" ); | |
}) | |
.delegate( ".ui-li>a", "focusout", function() { | |
$( this ).attr( "tabindex", "-1" ); | |
}) | |
.delegate( "li:not(.ui-disabled, .ui-li-divider)", "vclick", function( event ) { | |
var $this = $( this ), | |
// index of option tag to be selected | |
oldIndex = select[ 0 ].selectedIndex, | |
newIndex = $this.jqmData( "option-index" ), | |
option = self.optionElems[ newIndex ]; | |
// toggle selected status on the tag for multi selects | |
option.selected = isMultiple ? !option.selected : true; | |
// toggle checkbox class for multiple selects | |
if ( isMultiple ) { | |
$this.find( ".ui-icon" ) | |
.toggleClass( "ui-icon-checkbox-on", option.selected ) | |
.toggleClass( "ui-icon-checkbox-off", !option.selected ); | |
} | |
// trigger change if value changed | |
if ( isMultiple || oldIndex !== newIndex ) { | |
select.trigger( "change" ); | |
} | |
//hide custom select for single selects only | |
if ( !isMultiple ) { | |
self.close(); | |
} | |
event.preventDefault(); | |
}) | |
//keyboard events for menu items | |
.keydown(function( event ) { | |
var target = $( event.target ), | |
li = target.closest( "li" ), | |
prev, next; | |
// switch logic based on which key was pressed | |
switch ( event.keyCode ) { | |
// up or left arrow keys | |
case 38: | |
prev = li.prev(); | |
// if there's a previous option, focus it | |
if ( prev.length ) { | |
target | |
.blur() | |
.attr( "tabindex", "-1" ); | |
prev.find( "a" ).first().focus(); | |
} | |
return false; | |
break; | |
// down or right arrow keys | |
case 40: | |
next = li.next(); | |
// if there's a next option, focus it | |
if ( next.length ) { | |
target | |
.blur() | |
.attr( "tabindex", "-1" ); | |
next.find( "a" ).first().focus(); | |
} | |
return false; | |
break; | |
// If enter or space is pressed, trigger click | |
case 13: | |
case 32: | |
target.trigger( "vclick" ); | |
return false; | |
break; | |
} | |
}); | |
// button refocus ensures proper height calculation | |
// by removing the inline style and ensuring page inclusion | |
self.menuPage.bind( "pagehide", function(){ | |
self.list.appendTo( self.listbox ); | |
self._focusButton(); | |
}); | |
// Events on "screen" overlay | |
screen.bind( "vclick", function( event ) { | |
self.close(); | |
}); | |
// Close button on small overlays | |
self.headerClose.click(function() { | |
if ( self.menuType == "overlay" ) { | |
self.close(); | |
return false; | |
} | |
}); | |
} | |
}, | |
_buildList: function() { | |
var self = this, | |
o = this.options, | |
placeholder = this.placeholder, | |
optgroups = [], | |
lis = [], | |
dataIcon = self.isMultiple ? "checkbox-off" : "false"; | |
self.list.empty().filter( ".ui-listview" ).listview( "destroy" ); | |
// Populate menu with options from select element | |
self.select.find( "option" ).each(function( i ) { | |
var $this = $( this ), | |
$parent = $this.parent(), | |
text = $this.text(), | |
anchor = "<a href='#'>"+ text +"</a>", | |
classes = [], | |
extraAttrs = []; | |
// Are we inside an optgroup? | |
if ( $parent.is( "optgroup" ) ) { | |
var optLabel = $parent.attr( "label" ); | |
// has this optgroup already been built yet? | |
if ( $.inArray( optLabel, optgroups ) === -1 ) { | |
lis.push( "<li data-" + $.mobile.ns + "role='list-divider'>"+ optLabel +"</li>" ); | |
optgroups.push( optLabel ); | |
} | |
} | |
// Find placeholder text | |
// TODO: Are you sure you want to use getAttribute? ^RW | |
if ( !this.getAttribute( "value" ) || text.length == 0 || $this.jqmData( "placeholder" ) ) { | |
if ( o.hidePlaceholderMenuItems ) { | |
classes.push( "ui-selectmenu-placeholder" ); | |
} | |
placeholder = self.placeholder = text; | |
} | |
// support disabled option tags | |
if ( this.disabled ) { | |
classes.push( "ui-disabled" ); | |
extraAttrs.push( "aria-disabled='true'" ); | |
} | |
lis.push( "<li data-" + $.mobile.ns + "option-index='" + i + "' data-" + $.mobile.ns + "icon='"+ dataIcon +"' class='"+ classes.join(" ") + "' " + extraAttrs.join(" ") +">"+ anchor +"</li>" ) | |
}); | |
self.list.html( lis.join(" ") ); | |
self.list.find( "li" ) | |
.attr({ "role": "option", "tabindex": "-1" }) | |
.first().attr( "tabindex", "0" ); | |
// Hide header close link for single selects | |
if ( !this.isMultiple ) { | |
this.headerClose.hide(); | |
} | |
// Hide header if it's not a multiselect and there's no placeholder | |
if ( !this.isMultiple && !placeholder.length ) { | |
this.header.hide(); | |
} else { | |
this.headerTitle.text( this.placeholder ); | |
} | |
// Now populated, create listview | |
self.list.listview(); | |
}, | |
refresh: function( forceRebuild ) { | |
var self = this, | |
select = this.element, | |
isMultiple = this.isMultiple, | |
options = this.optionElems = select.find( "option" ), | |
selected = options.filter( ":selected" ), | |
// return an array of all selected index's | |
indicies = selected.map(function() { | |
return options.index( this ); | |
}).get(); | |
if ( !self.options.nativeMenu && | |
( forceRebuild || select[0].options.length != self.list.find( "li" ).length ) ) { | |
self._buildList(); | |
} | |
self.button.find( ".ui-btn-text" ) | |
.text(function() { | |
if ( !isMultiple ) { | |
return selected.text(); | |
} | |
return selected.length ? selected.map(function() { | |
return $( this ).text(); | |
}).get().join( ", " ) : self.placeholder; | |
}); | |
// multiple count inside button | |
if ( isMultiple ) { | |
self.buttonCount[ selected.length > 1 ? "show" : "hide" ]().text( selected.length ); | |
} | |
if ( !self.options.nativeMenu ) { | |
self.list.find( "li:not(.ui-li-divider)" ) | |
.removeClass( $.mobile.activeBtnClass ) | |
.attr( "aria-selected", false ) | |
.each(function( i ) { | |
if ( $.inArray( i, indicies ) > -1 ) { | |
var item = $( this ).addClass( $.mobile.activeBtnClass ); | |
// Aria selected attr | |
item.find( "a" ).attr( "aria-selected", true ); | |
// Multiple selects: add the "on" checkbox state to the icon | |
if ( isMultiple ) { | |
item.find( ".ui-icon" ).removeClass( "ui-icon-checkbox-off" ).addClass( "ui-icon-checkbox-on" ); | |
} | |
} | |
}); | |
} | |
}, | |
open: function() { | |
if ( this.options.disabled || this.options.nativeMenu ) { | |
return; | |
} | |
var self = this, | |
menuHeight = self.list.parent().outerHeight(), | |
menuWidth = self.list.parent().outerWidth(), | |
scrollTop = $( window ).scrollTop(), | |
btnOffset = self.button.offset().top, | |
screenHeight = window.innerHeight, | |
screenWidth = window.innerWidth; | |
//add active class to button | |
self.button.addClass( $.mobile.activeBtnClass ); | |
//remove after delay | |
setTimeout(function() { | |
self.button.removeClass( $.mobile.activeBtnClass ); | |
}, 300); | |
function focusMenuItem() { | |
self.list.find( ".ui-btn-active" ).focus(); | |
} | |
if ( menuHeight > screenHeight - 80 || !$.support.scrollTop ) { | |
// prevent the parent page from being removed from the DOM, | |
// otherwise the results of selecting a list item in the dialog | |
// fall into a black hole | |
self.thisPage.unbind( "pagehide.remove" ); | |
//for webos (set lastscroll using button offset) | |
if ( scrollTop == 0 && btnOffset > screenHeight ) { | |
self.thisPage.one( "pagehide", function() { | |
$( this ).jqmData( "lastScroll", btnOffset ); | |
}); | |
} | |
self.menuPage.one( "pageshow", function() { | |
// silentScroll() is called whenever a page is shown to restore | |
// any previous scroll position the page may have had. We need to | |
// wait for the "silentscroll" event before setting focus to avoid | |
// the browser"s "feature" which offsets rendering to make sure | |
// whatever has focus is in view. | |
$( window ).one( "silentscroll", function() { | |
focusMenuItem(); | |
}); | |
self.isOpen = true; | |
}); | |
self.menuType = "page"; | |
self.menuPageContent.append( self.list ); | |
$.mobile.changePage( self.menuPage, { | |
transition: $.mobile.defaultDialogTransition | |
}); | |
} else { | |
self.menuType = "overlay"; | |
self.screen.height( $(document).height() ) | |
.removeClass( "ui-screen-hidden" ); | |
// Try and center the overlay over the button | |
var roomtop = btnOffset - scrollTop, | |
roombot = scrollTop + screenHeight - btnOffset, | |
halfheight = menuHeight / 2, | |
maxwidth = parseFloat( self.list.parent().css( "max-width" ) ), | |
newtop, newleft; | |
if ( roomtop > menuHeight / 2 && roombot > menuHeight / 2 ) { | |
newtop = btnOffset + ( self.button.outerHeight() / 2 ) - halfheight; | |
} else { | |
// 30px tolerance off the edges | |
newtop = roomtop > roombot ? scrollTop + screenHeight - menuHeight - 30 : scrollTop + 30; | |
} | |
// If the menuwidth is smaller than the screen center is | |
if ( menuWidth < maxwidth ) { | |
newleft = ( screenWidth - menuWidth ) / 2; | |
} else { | |
//otherwise insure a >= 30px offset from the left | |
newleft = self.button.offset().left + self.button.outerWidth() / 2 - menuWidth / 2; | |
// 30px tolerance off the edges | |
if ( newleft < 30 ) { | |
newleft = 30; | |
} else if ( ( newleft + menuWidth ) > screenWidth ) { | |
newleft = screenWidth - menuWidth - 30; | |
} | |
} | |
self.listbox.append( self.list ) | |
.removeClass( "ui-selectmenu-hidden" ) | |
.css({ | |
top: newtop, | |
left: newleft | |
}) | |
.addClass( "in" ); | |
focusMenuItem(); | |
// duplicate with value set in page show for dialog sized selects | |
self.isOpen = true; | |
} | |
}, | |
_focusButton : function(){ | |
var self = this; | |
setTimeout(function() { | |
self.button.focus(); | |
}, 40); | |
}, | |
close: function() { | |
if ( this.options.disabled || !this.isOpen || this.options.nativeMenu ) { | |
return; | |
} | |
var self = this; | |
if ( self.menuType == "page" ) { | |
// rebind the page remove that was unbound in the open function | |
// to allow for the parent page removal from actions other than the use | |
// of a dialog sized custom select | |
self.thisPage.bind( "pagehide.remove", function(){ | |
$(this).remove(); | |
}); | |
// doesn't solve the possible issue with calling change page | |
// where the objects don't define data urls which prevents dialog key | |
// stripping - changePage has incoming refactor | |
window.history.back(); | |
} else{ | |
self.screen.addClass( "ui-screen-hidden" ); | |
self.listbox.addClass( "ui-selectmenu-hidden" ).removeAttr( "style" ).removeClass( "in" ); | |
self.list.appendTo( self.listbox ); | |
self._focusButton(); | |
} | |
// allow the dialog to be closed again | |
this.isOpen = false; | |
}, | |
disable: function() { | |
this.element.attr( "disabled", true ); | |
this.button.addClass( "ui-disabled" ).attr( "aria-disabled", true ); | |
return this._setOption( "disabled", true ); | |
}, | |
enable: function() { | |
this.element.attr( "disabled", false ); | |
this.button.removeClass( "ui-disabled" ).attr( "aria-disabled", false ); | |
return this._setOption( "disabled", false ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.selectmenu.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.selectmenu(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : plugin for making button-like links | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, undefined ) { | |
$.fn.buttonMarkup = function( options ) { | |
return this.each( function() { | |
var el = $( this ), | |
o = $.extend( {}, $.fn.buttonMarkup.defaults, el.jqmData(), options ), | |
// Classes Defined | |
innerClass = "ui-btn-inner", | |
buttonClass, iconClass, | |
themedParent, wrap; | |
if ( attachEvents ) { | |
attachEvents(); | |
} | |
// if not, try to find closest theme container | |
if ( !o.theme ) { | |
themedParent = el.closest( "[class*='ui-bar-'],[class*='ui-body-']" ); | |
o.theme = themedParent.length ? | |
/ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) )[2] : | |
"c"; | |
} | |
buttonClass = "ui-btn ui-btn-up-" + o.theme; | |
if ( o.inline ) { | |
buttonClass += " ui-btn-inline"; | |
} | |
if ( o.icon ) { | |
o.icon = "ui-icon-" + o.icon; | |
o.iconpos = o.iconpos || "left"; | |
iconClass = "ui-icon " + o.icon; | |
if ( o.iconshadow ) { | |
iconClass += " ui-icon-shadow"; | |
} | |
} | |
if ( o.iconpos ) { | |
buttonClass += " ui-btn-icon-" + o.iconpos; | |
if ( o.iconpos == "notext" && !el.attr( "title" ) ) { | |
el.attr( "title", el.text() ); | |
} | |
} | |
if ( o.corners ) { | |
buttonClass += " ui-btn-corner-all"; | |
innerClass += " ui-btn-corner-all"; | |
} | |
if ( o.shadow ) { | |
buttonClass += " ui-shadow"; | |
} | |
el.attr( "data-" + $.mobile.ns + "theme", o.theme ) | |
.addClass( buttonClass ); | |
wrap = ( "<D class='" + innerClass + "'><D class='ui-btn-text'></D>" + | |
( o.icon ? "<span class='" + iconClass + "'></span>" : "" ) + | |
"</D>" ).replace( /D/g, o.wrapperEls ); | |
el.wrapInner( wrap ); | |
}); | |
}; | |
$.fn.buttonMarkup.defaults = { | |
corners: true, | |
shadow: true, | |
iconshadow: true, | |
wrapperEls: "span" | |
}; | |
function closestEnabledButton( element ) { | |
while ( element ) { | |
var $ele = $( element ); | |
if ( $ele.hasClass( "ui-btn" ) && !$ele.hasClass( "ui-disabled" ) ) { | |
break; | |
} | |
element = element.parentNode; | |
} | |
return element; | |
} | |
var attachEvents = function() { | |
$( document ).bind( { | |
"vmousedown": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme ); | |
} | |
}, | |
"vmousecancel vmouseup": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme ); | |
} | |
}, | |
"vmouseover focus": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme ); | |
} | |
}, | |
"vmouseout blur": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-hover-" + theme ).addClass( "ui-btn-up-" + theme ); | |
} | |
} | |
}); | |
attachEvents = null; | |
}; | |
//links in bars, or those with data-role become buttons | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a, .ui-bar > :jqmData(role='controlgroup') > a", e.target ) | |
.not( ".ui-btn, :jqmData(role='none'), :jqmData(role='nojs')" ) | |
.buttonMarkup(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework: "controlgroup" plugin - corner-rounding for groups of buttons, checks, radios, etc | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.fn.controlgroup = function( options ) { | |
return this.each(function() { | |
var $el = $( this ), | |
o = $.extend({ | |
direction: $el.jqmData( "type" ) || "vertical", | |
shadow: false, | |
excludeInvisible: true | |
}, options ), | |
groupheading = $el.find( ">legend" ), | |
flCorners = o.direction == "horizontal" ? [ "ui-corner-left", "ui-corner-right" ] : [ "ui-corner-top", "ui-corner-bottom" ], | |
type = $el.find( "input:eq(0)" ).attr( "type" ); | |
// Replace legend with more stylable replacement div | |
if ( groupheading.length ) { | |
$el.wrapInner( "<div class='ui-controlgroup-controls'></div>" ); | |
$( "<div role='heading' class='ui-controlgroup-label'>" + groupheading.html() + "</div>" ).insertBefore( $el.children(0) ); | |
groupheading.remove(); | |
} | |
$el.addClass( "ui-corner-all ui-controlgroup ui-controlgroup-" + o.direction ); | |
// TODO: This should be moved out to the closure | |
// otherwise it is redefined each time controlgroup() is called | |
function flipClasses( els ) { | |
els.removeClass( "ui-btn-corner-all ui-shadow" ) | |
.eq( 0 ).addClass( flCorners[ 0 ] ) | |
.end() | |
.filter( ":last" ).addClass( flCorners[ 1 ] ).addClass( "ui-controlgroup-last" ); | |
} | |
flipClasses( $el.find( ".ui-btn" + ( o.excludeInvisible ? ":visible" : "" ) ) ); | |
flipClasses( $el.find( ".ui-btn-inner" ) ); | |
if ( o.shadow ) { | |
$el.addClass( "ui-shadow" ); | |
} | |
}); | |
}; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='controlgroup')", e.target ).controlgroup({ excludeInvisible: false }); | |
}); | |
})(jQuery);/* | |
* jQuery Mobile Framework : "fieldcontain" plugin - simple class additions to make form row separators | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$( document ).bind( "pagecreate create", function( e ){ | |
//links within content areas | |
$( e.target ) | |
.find( "a" ) | |
.not( ".ui-btn, .ui-link-inherit, :jqmData(role='none'), :jqmData(role='nojs')" ) | |
.addClass( "ui-link" ); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "fixHeaderFooter" plugin - on-demand positioning for headers,footers | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
var slideDownClass = "ui-header-fixed ui-fixed-inline fade", | |
slideUpClass = "ui-footer-fixed ui-fixed-inline fade", | |
slideDownSelector = ".ui-header:jqmData(position='fixed')", | |
slideUpSelector = ".ui-footer:jqmData(position='fixed')"; | |
$.fn.fixHeaderFooter = function( options ) { | |
if ( !$.support.scrollTop ) { | |
return this; | |
} | |
return this.each(function() { | |
var $this = $( this ); | |
if ( $this.jqmData( "fullscreen" ) ) { | |
$this.addClass( "ui-page-fullscreen" ); | |
} | |
// Should be slidedown | |
$this.find( slideDownSelector ).addClass( slideDownClass ); | |
// Should be slideup | |
$this.find( slideUpSelector ).addClass( slideUpClass ); | |
}); | |
}; | |
// single controller for all showing,hiding,toggling | |
$.mobile.fixedToolbars = (function() { | |
if ( !$.support.scrollTop ) { | |
return; | |
} | |
var stickyFooter, delayTimer, | |
currentstate = "inline", | |
autoHideMode = false, | |
showDelay = 100, | |
ignoreTargets = "a,input,textarea,select,button,label,.ui-header-fixed,.ui-footer-fixed", | |
toolbarSelector = ".ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last", | |
// for storing quick references to duplicate footers | |
supportTouch = $.support.touch, | |
touchStartEvent = supportTouch ? "touchstart" : "mousedown", | |
touchStopEvent = supportTouch ? "touchend" : "mouseup", | |
stateBefore = null, | |
scrollTriggered = false, | |
touchToggleEnabled = true; | |
function showEventCallback( event ) { | |
// An event that affects the dimensions of the visual viewport has | |
// been triggered. If the header and/or footer for the current page are in overlay | |
// mode, we want to hide them, and then fire off a timer to show them at a later | |
// point. Events like a resize can be triggered continuously during a scroll, on | |
// some platforms, so the timer is used to delay the actual positioning until the | |
// flood of events have subsided. | |
// | |
// If we are in autoHideMode, we don't do anything because we know the scroll | |
// callbacks for the plugin will fire off a show when the scrolling has stopped. | |
if ( !autoHideMode && currentstate === "overlay" ) { | |
if ( !delayTimer ) { | |
$.mobile.fixedToolbars.hide( true ); | |
} | |
$.mobile.fixedToolbars.startShowTimer(); | |
} | |
} | |
$(function() { | |
var $document = $( document ), | |
$window = $( window ); | |
$document | |
.bind( "vmousedown", function( event ) { | |
if ( touchToggleEnabled ) { | |
stateBefore = currentstate; | |
} | |
}) | |
.bind( "vclick", function( event ) { | |
if ( touchToggleEnabled ) { | |
if ( $(event.target).closest( ignoreTargets ).length ) { | |
return; | |
} | |
if ( !scrollTriggered ) { | |
$.mobile.fixedToolbars.toggle( stateBefore ); | |
stateBefore = null; | |
} | |
} | |
}) | |
.bind( "silentscroll", showEventCallback ); | |
// The below checks first for a $(document).scrollTop() value, and if zero, binds scroll events to $(window) instead. | |
// If the scrollTop value is actually zero, both will return zero anyway. | |
// | |
// Works with $(document), not $(window) : Opera Mobile (WinMO phone; kinda broken anyway) | |
// Works with $(window), not $(document) : IE 7/8 | |
// Works with either $(window) or $(document) : Chrome, FF 3.6/4, Android 1.6/2.1, iOS | |
// Needs work either way : BB5, Opera Mobile (iOS) | |
( ( $document.scrollTop() === 0 ) ? $window : $document ) | |
.bind( "scrollstart", function( event ) { | |
scrollTriggered = true; | |
if ( stateBefore === null ) { | |
stateBefore = currentstate; | |
} | |
// We only enter autoHideMode if the headers/footers are in | |
// an overlay state or the show timer was started. If the | |
// show timer is set, clear it so the headers/footers don't | |
// show up until after we're done scrolling. | |
var isOverlayState = stateBefore == "overlay"; | |
autoHideMode = isOverlayState || !!delayTimer; | |
if ( autoHideMode ) { | |
$.mobile.fixedToolbars.clearShowTimer(); | |
if ( isOverlayState ) { | |
$.mobile.fixedToolbars.hide( true ); | |
} | |
} | |
}) | |
.bind( "scrollstop", function( event ) { | |
if ( $( event.target ).closest( ignoreTargets ).length ) { | |
return; | |
} | |
scrollTriggered = false; | |
if ( autoHideMode ) { | |
$.mobile.fixedToolbars.startShowTimer(); | |
autoHideMode = false; | |
} | |
stateBefore = null; | |
}); | |
$window.bind( "resize", showEventCallback ); | |
}); | |
// 1. Before page is shown, check for duplicate footer | |
// 2. After page is shown, append footer to new page | |
$( ".ui-page" ) | |
.live( "pagebeforeshow", function( event, ui ) { | |
var page = $( event.target ), | |
footer = page.find( ":jqmData(role='footer')" ), | |
id = footer.data( "id" ), | |
prevPage = ui.prevPage, | |
prevFooter = prevPage && prevPage.find( ":jqmData(role='footer')" ), | |
prevFooterMatches = prevFooter.length && prevFooter.jqmData( "id" ) === id; | |
if ( id && prevFooterMatches ) { | |
stickyFooter = footer; | |
setTop( stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer ) ); | |
} | |
}) | |
.live( "pageshow", function( event, ui ) { | |
var $this = $( this ); | |
if ( stickyFooter && stickyFooter.length ) { | |
setTimeout(function() { | |
setTop( stickyFooter.appendTo( $this ).addClass( "fade" ) ); | |
stickyFooter = null; | |
}, 500); | |
} | |
$.mobile.fixedToolbars.show( true, this ); | |
}); | |
// When a collapsiable is hidden or shown we need to trigger the fixed toolbar to reposition itself (#1635) | |
$( ".ui-collapsible-contain" ).live( "collapse expand", showEventCallback ); | |
// element.getBoundingClientRect() is broken in iOS 3.2.1 on the iPad. The | |
// coordinates inside of the rect it returns don't have the page scroll position | |
// factored out of it like the other platforms do. To get around this, | |
// we'll just calculate the top offset the old fashioned way until core has | |
// a chance to figure out how to handle this situation. | |
// | |
// TODO: We'll need to get rid of getOffsetTop() once a fix gets folded into core. | |
function getOffsetTop( ele ) { | |
var top = 0, | |
op, body; | |
if ( ele ) { | |
body = document.body; | |
op = ele.offsetParent; | |
top = ele.offsetTop; | |
while ( ele && ele != body ) { | |
top += ele.scrollTop || 0; | |
if ( ele == op ) { | |
top += op.offsetTop; | |
op = ele.offsetParent; | |
} | |
ele = ele.parentNode; | |
} | |
} | |
return top; | |
} | |
function setTop( el ) { | |
var fromTop = $(window).scrollTop(), | |
thisTop = getOffsetTop( el[ 0 ] ), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. | |
thisCSStop = el.css( "top" ) == "auto" ? 0 : parseFloat(el.css( "top" )), | |
screenHeight = window.innerHeight, | |
thisHeight = el.outerHeight(), | |
useRelative = el.parents( ".ui-page:not(.ui-page-fullscreen)" ).length, | |
relval; | |
if ( el.is( ".ui-header-fixed" ) ) { | |
relval = fromTop - thisTop + thisCSStop; | |
if ( relval < thisTop ) { | |
relval = 0; | |
} | |
return el.css( "top", useRelative ? relval : fromTop ); | |
} else { | |
// relval = -1 * (thisTop - (fromTop + screenHeight) + thisCSStop + thisHeight); | |
// if ( relval > thisTop ) { relval = 0; } | |
relval = fromTop + screenHeight - thisHeight - (thisTop - thisCSStop ); | |
return el.css( "top", useRelative ? relval : fromTop + screenHeight - thisHeight ); | |
} | |
} | |
// Exposed methods | |
return { | |
show: function( immediately, page ) { | |
$.mobile.fixedToolbars.clearShowTimer(); | |
currentstate = "overlay"; | |
var $ap = page ? $( page ) : | |
( $.mobile.activePage ? $.mobile.activePage : | |
$( ".ui-page-active" ) ); | |
return $ap.children( toolbarSelector ).each(function() { | |
var el = $( this ), | |
fromTop = $( window ).scrollTop(), | |
// el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. | |
thisTop = getOffsetTop( el[ 0 ] ), | |
screenHeight = window.innerHeight, | |
thisHeight = el.outerHeight(), | |
alreadyVisible = ( el.is( ".ui-header-fixed" ) && fromTop <= thisTop + thisHeight ) || | |
( el.is( ".ui-footer-fixed" ) && thisTop <= fromTop + screenHeight ); | |
// Add state class | |
el.addClass( "ui-fixed-overlay" ).removeClass( "ui-fixed-inline" ); | |
if ( !alreadyVisible && !immediately ) { | |
el.animationComplete(function() { | |
el.removeClass( "in" ); | |
}).addClass( "in" ); | |
} | |
setTop(el); | |
}); | |
}, | |
hide: function( immediately ) { | |
currentstate = "inline"; | |
var $ap = $.mobile.activePage ? $.mobile.activePage : | |
$( ".ui-page-active" ); | |
return $ap.children( toolbarSelector ).each(function() { | |
var el = $(this), | |
thisCSStop = el.css( "top" ), | |
classes; | |
thisCSStop = thisCSStop == "auto" ? 0 : | |
parseFloat(thisCSStop); | |
// Add state class | |
el.addClass( "ui-fixed-inline" ).removeClass( "ui-fixed-overlay" ); | |
if ( thisCSStop < 0 || ( el.is( ".ui-header-fixed" ) && thisCSStop !== 0 ) ) { | |
if ( immediately ) { | |
el.css( "top", 0); | |
} else { | |
if ( el.css( "top" ) !== "auto" && parseFloat( el.css( "top" ) ) !== 0 ) { | |
classes = "out reverse"; | |
el.animationComplete(function() { | |
el.removeClass( classes ).css( "top", 0 ); | |
}).addClass( classes ); | |
} | |
} | |
} | |
}); | |
}, | |
startShowTimer: function() { | |
$.mobile.fixedToolbars.clearShowTimer(); | |
var args = [].slice.call( arguments ); | |
delayTimer = setTimeout(function() { | |
delayTimer = undefined; | |
$.mobile.fixedToolbars.show.apply( null, args ); | |
}, showDelay); | |
}, | |
clearShowTimer: function() { | |
if ( delayTimer ) { | |
clearTimeout( delayTimer ); | |
} | |
delayTimer = undefined; | |
}, | |
toggle: function( from ) { | |
if ( from ) { | |
currentstate = from; | |
} | |
return ( currentstate === "overlay" ) ? $.mobile.fixedToolbars.hide() : | |
$.mobile.fixedToolbars.show(); | |
}, | |
setTouchToggleEnabled: function( enabled ) { | |
touchToggleEnabled = enabled; | |
} | |
}; | |
})(); | |
// TODO - Deprecated namepace on $. Remove in a later release | |
$.fixedToolbars = $.mobile.fixedToolbars; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( event ) { | |
if ( $( ":jqmData(position='fixed')", event.target ).length ) { | |
$( event.target ).each(function() { | |
if ( !$.support.scrollTop ) { | |
return this; | |
} | |
var $this = $( this ); | |
if ( $this.jqmData( "fullscreen" ) ) { | |
$this.addClass( "ui-page-fullscreen" ); | |
} | |
// Should be slidedown | |
$this.find( slideDownSelector ).addClass( slideDownClass ); | |
// Should be slideup | |
$this.find( slideUpSelector ).addClass( slideUpClass ); | |
}) | |
} | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : resolution and CSS media query related helpers and behavior | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
var $window = $( window ), | |
$html = $( "html" ), | |
//media-query-like width breakpoints, which are translated to classes on the html element | |
resolutionBreakpoints = [ 320, 480, 768, 1024 ]; | |
/* | |
private function for adding/removing breakpoint classes to HTML element for faux media-query support | |
It does not require media query support, instead using JS to detect screen width > cross-browser support | |
This function is called on orientationchange, resize, and mobileinit, and is bound via the 'htmlclass' event namespace | |
*/ | |
function detectResolutionBreakpoints() { | |
var currWidth = $window.width(), | |
minPrefix = "min-width-", | |
maxPrefix = "max-width-", | |
minBreakpoints = [], | |
maxBreakpoints = [], | |
unit = "px", | |
breakpointClasses; | |
$html.removeClass( minPrefix + resolutionBreakpoints.join(unit + " " + minPrefix) + unit + " " + | |
maxPrefix + resolutionBreakpoints.join( unit + " " + maxPrefix) + unit ); | |
$.each( resolutionBreakpoints, function( i, breakPoint ) { | |
if( currWidth >= breakPoint ) { | |
minBreakpoints.push( minPrefix + breakPoint + unit ); | |
} | |
if( currWidth <= breakPoint ) { | |
maxBreakpoints.push( maxPrefix + breakPoint + unit ); | |
} | |
}); | |
if ( minBreakpoints.length ) { | |
breakpointClasses = minBreakpoints.join(" "); | |
} | |
if ( maxBreakpoints.length ) { | |
breakpointClasses += " " + maxBreakpoints.join(" "); | |
} | |
$html.addClass( breakpointClasses ); | |
}; | |
/* $.mobile.addResolutionBreakpoints method: | |
pass either a number or an array of numbers and they'll be added to the min/max breakpoint classes | |
Examples: | |
$.mobile.addResolutionBreakpoints( 500 ); | |
$.mobile.addResolutionBreakpoints( [500, 1200] ); | |
*/ | |
$.mobile.addResolutionBreakpoints = function( newbps ) { | |
if( $.type( newbps ) === "array" ){ | |
resolutionBreakpoints = resolutionBreakpoints.concat( newbps ); | |
} else { | |
resolutionBreakpoints.push( newbps ); | |
} | |
resolutionBreakpoints.sort(function( a, b ) { | |
return a - b; | |
}); | |
detectResolutionBreakpoints(); | |
}; | |
/* on mobileinit, add classes to HTML element | |
and set handlers to update those on orientationchange and resize | |
*/ | |
$( document ).bind( "mobileinit.htmlclass", function() { | |
// bind to orientationchange and resize | |
// to add classes to HTML element for min/max breakpoints and orientation | |
var ev = $.support.orientation; | |
$window.bind( "orientationchange.htmlclass throttledResize.htmlclass", function( event ) { | |
// add orientation class to HTML element on flip/resize. | |
if ( event.orientation ) { | |
$html.removeClass( "portrait landscape" ).addClass( event.orientation ); | |
} | |
// add classes to HTML element for min/max breakpoints | |
detectResolutionBreakpoints(); | |
}); | |
}); | |
/* Manually trigger an orientationchange event when the dom ready event fires. | |
This will ensure that any viewport meta tag that may have been injected | |
has taken effect already, allowing us to properly calculate the width of the | |
document. | |
*/ | |
$(function() { | |
//trigger event manually | |
$window.trigger( "orientationchange.htmlclass" ); | |
}); | |
})(jQuery);/*! | |
* jQuery Mobile v@VERSION | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
var $html = $( "html" ), | |
$head = $( "head" ), | |
$window = $( window ); | |
//trigger mobileinit event - useful hook for configuring $.mobile settings before they're used | |
$( window.document ).trigger( "mobileinit" ); | |
//support conditions | |
//if device support condition(s) aren't met, leave things as they are -> a basic, usable experience, | |
//otherwise, proceed with the enhancements | |
if ( !$.mobile.gradeA() ) { | |
return; | |
} | |
// override ajaxEnabled on platforms that have known conflicts with hash history updates | |
// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini) | |
if( $.mobile.ajaxBlacklist ){ | |
$.mobile.ajaxEnabled = false; | |
} | |
//add mobile, initial load "rendering" classes to docEl | |
$html.addClass( "ui-mobile ui-mobile-rendering" ); | |
//loading div which appears during Ajax requests | |
//will not appear if $.mobile.loadingMessage is false | |
var $loader = $( "<div class='ui-loader ui-body-a ui-corner-all'><span class='ui-icon ui-icon-loading spin'></span><h1></h1></div>" ); | |
$.extend($.mobile, { | |
// turn on/off page loading message. | |
showPageLoadingMsg: function() { | |
if( $.mobile.loadingMessage ){ | |
var activeBtn = $( "." + $.mobile.activeBtnClass ).first(); | |
$loader | |
.find( "h1" ) | |
.text( $.mobile.loadingMessage ) | |
.end() | |
.appendTo( $.mobile.pageContainer ) | |
//position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top | |
.css( { | |
top: $.support.scrollTop && $(window).scrollTop() + $(window).height() / 2 || | |
activeBtn.length && activeBtn.offset().top || 100 | |
} ); | |
} | |
$html.addClass( "ui-loading" ); | |
}, | |
hidePageLoadingMsg: function() { | |
$html.removeClass( "ui-loading" ); | |
}, | |
// XXX: deprecate for 1.0 | |
pageLoading: function ( done ) { | |
if ( done ) { | |
$.mobile.hidePageLoadingMsg(); | |
} else { | |
$.mobile.showPageLoadingMsg(); | |
} | |
}, | |
// find and enhance the pages in the dom and transition to the first page. | |
initializePage: function(){ | |
//find present pages | |
var $pages = $( ":jqmData(role='page')" ); | |
//if no pages are found, create one with body's inner html | |
if( !$pages.length ){ | |
$pages = $( "body" ).wrapInner( "<div data-" + $.mobile.ns + "role='page'></div>" ).children( 0 ); | |
} | |
//add dialogs, set data-url attrs | |
$pages.add( ":jqmData(role='dialog')" ).each(function(){ | |
var $this = $(this); | |
// unless the data url is already set set it to the id | |
if( !$this.jqmData('url') ){ | |
$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) ); | |
} | |
}); | |
//define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback) | |
$.mobile.firstPage = $pages.first(); | |
//define page container | |
$.mobile.pageContainer = $pages.first().parent().addClass( "ui-mobile-viewport" ); | |
//cue page loading message | |
$.mobile.showPageLoadingMsg(); | |
// if hashchange listening is disabled or there's no hash deeplink, change to the first page in the DOM | |
if( !$.mobile.hashListeningEnabled || !$.mobile.path.stripHash( location.hash ) ){ | |
$.mobile.changePage( $.mobile.firstPage, { transition: "none", reverse: true, changeHash: false, fromHashChange: true } ); | |
} | |
// otherwise, trigger a hashchange to load a deeplink | |
else { | |
$window.trigger( "hashchange", [ true ] ); | |
} | |
} | |
}); | |
//initialize events now, after mobileinit has occurred | |
$.mobile._registerInternalEvents(); | |
//check which scrollTop value should be used by scrolling to 1 immediately at domready | |
//then check what the scroll top is. Android will report 0... others 1 | |
//note that this initial scroll won't hide the address bar. It's just for the check. | |
$(function(){ | |
window.scrollTo( 0, 1 ); | |
//if defaultHomeScroll hasn't been set yet, see if scrollTop is 1 | |
//it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar) | |
//so if it's 1, use 0 from now on | |
$.mobile.defaultHomeScroll = ( !$.support.scrollTop || $(window).scrollTop() === 1 ) ? 0 : 1; | |
//dom-ready inits | |
if( $.mobile.autoInitializePage ){ | |
$( $.mobile.initializePage ); | |
} | |
//window load event | |
//hide iOS browser chrome on load | |
$window.load( $.mobile.silentScroll ); | |
}); | |
})( jQuery, this ); | |
/*! | |
* jQuery Mobile v1.0rc1 | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
/*! | |
* jQuery UI Widget @VERSION | |
* | |
* Copyright 2010, AUTHORS.txt (http://jqueryui.com/about) | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
* | |
* http://docs.jquery.com/UI/Widget | |
*/ | |
(function( $, undefined ) { | |
// jQuery 1.4+ | |
if ( $.cleanData ) { | |
var _cleanData = $.cleanData; | |
$.cleanData = function( elems ) { | |
for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { | |
$( elem ).triggerHandler( "remove" ); | |
} | |
_cleanData( elems ); | |
}; | |
} else { | |
var _remove = $.fn.remove; | |
$.fn.remove = function( selector, keepData ) { | |
return this.each(function() { | |
if ( !keepData ) { | |
if ( !selector || $.filter( selector, [ this ] ).length ) { | |
$( "*", this ).add( [ this ] ).each(function() { | |
$( this ).triggerHandler( "remove" ); | |
}); | |
} | |
} | |
return _remove.call( $(this), selector, keepData ); | |
}); | |
}; | |
} | |
$.widget = function( name, base, prototype ) { | |
var namespace = name.split( "." )[ 0 ], | |
fullName; | |
name = name.split( "." )[ 1 ]; | |
fullName = namespace + "-" + name; | |
if ( !prototype ) { | |
prototype = base; | |
base = $.Widget; | |
} | |
// create selector for plugin | |
$.expr[ ":" ][ fullName ] = function( elem ) { | |
return !!$.data( elem, name ); | |
}; | |
$[ namespace ] = $[ namespace ] || {}; | |
$[ namespace ][ name ] = function( options, element ) { | |
// allow instantiation without initializing for simple inheritance | |
if ( arguments.length ) { | |
this._createWidget( options, element ); | |
} | |
}; | |
var basePrototype = new base(); | |
// we need to make the options hash a property directly on the new instance | |
// otherwise we'll modify the options hash on the prototype that we're | |
// inheriting from | |
// $.each( basePrototype, function( key, val ) { | |
// if ( $.isPlainObject(val) ) { | |
// basePrototype[ key ] = $.extend( {}, val ); | |
// } | |
// }); | |
basePrototype.options = $.extend( true, {}, basePrototype.options ); | |
$[ namespace ][ name ].prototype = $.extend( true, basePrototype, { | |
namespace: namespace, | |
widgetName: name, | |
widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name, | |
widgetBaseClass: fullName | |
}, prototype ); | |
$.widget.bridge( name, $[ namespace ][ name ] ); | |
}; | |
$.widget.bridge = function( name, object ) { | |
$.fn[ name ] = function( options ) { | |
var isMethodCall = typeof options === "string", | |
args = Array.prototype.slice.call( arguments, 1 ), | |
returnValue = this; | |
// allow multiple hashes to be passed on init | |
options = !isMethodCall && args.length ? | |
$.extend.apply( null, [ true, options ].concat(args) ) : | |
options; | |
// prevent calls to internal methods | |
if ( isMethodCall && options.charAt( 0 ) === "_" ) { | |
return returnValue; | |
} | |
if ( isMethodCall ) { | |
this.each(function() { | |
var instance = $.data( this, name ); | |
if ( !instance ) { | |
throw "cannot call methods on " + name + " prior to initialization; " + | |
"attempted to call method '" + options + "'"; | |
} | |
if ( !$.isFunction( instance[options] ) ) { | |
throw "no such method '" + options + "' for " + name + " widget instance"; | |
} | |
var methodValue = instance[ options ].apply( instance, args ); | |
if ( methodValue !== instance && methodValue !== undefined ) { | |
returnValue = methodValue; | |
return false; | |
} | |
}); | |
} else { | |
this.each(function() { | |
var instance = $.data( this, name ); | |
if ( instance ) { | |
instance.option( options || {} )._init(); | |
} else { | |
$.data( this, name, new object( options, this ) ); | |
} | |
}); | |
} | |
return returnValue; | |
}; | |
}; | |
$.Widget = function( options, element ) { | |
// allow instantiation without initializing for simple inheritance | |
if ( arguments.length ) { | |
this._createWidget( options, element ); | |
} | |
}; | |
$.Widget.prototype = { | |
widgetName: "widget", | |
widgetEventPrefix: "", | |
options: { | |
disabled: false | |
}, | |
_createWidget: function( options, element ) { | |
// $.widget.bridge stores the plugin instance, but we do it anyway | |
// so that it's stored even before the _create function runs | |
$.data( element, this.widgetName, this ); | |
this.element = $( element ); | |
this.options = $.extend( true, {}, | |
this.options, | |
this._getCreateOptions(), | |
options ); | |
var self = this; | |
this.element.bind( "remove." + this.widgetName, function() { | |
self.destroy(); | |
}); | |
this._create(); | |
this._trigger( "create" ); | |
this._init(); | |
}, | |
_getCreateOptions: function() { | |
var options = {}; | |
if ( $.metadata ) { | |
options = $.metadata.get( element )[ this.widgetName ]; | |
} | |
return options; | |
}, | |
_create: function() {}, | |
_init: function() {}, | |
destroy: function() { | |
this.element | |
.unbind( "." + this.widgetName ) | |
.removeData( this.widgetName ); | |
this.widget() | |
.unbind( "." + this.widgetName ) | |
.removeAttr( "aria-disabled" ) | |
.removeClass( | |
this.widgetBaseClass + "-disabled " + | |
"ui-state-disabled" ); | |
}, | |
widget: function() { | |
return this.element; | |
}, | |
option: function( key, value ) { | |
var options = key; | |
if ( arguments.length === 0 ) { | |
// don't return a reference to the internal hash | |
return $.extend( {}, this.options ); | |
} | |
if (typeof key === "string" ) { | |
if ( value === undefined ) { | |
return this.options[ key ]; | |
} | |
options = {}; | |
options[ key ] = value; | |
} | |
this._setOptions( options ); | |
return this; | |
}, | |
_setOptions: function( options ) { | |
var self = this; | |
$.each( options, function( key, value ) { | |
self._setOption( key, value ); | |
}); | |
return this; | |
}, | |
_setOption: function( key, value ) { | |
this.options[ key ] = value; | |
if ( key === "disabled" ) { | |
this.widget() | |
[ value ? "addClass" : "removeClass"]( | |
this.widgetBaseClass + "-disabled" + " " + | |
"ui-state-disabled" ) | |
.attr( "aria-disabled", value ); | |
} | |
return this; | |
}, | |
enable: function() { | |
return this._setOption( "disabled", false ); | |
}, | |
disable: function() { | |
return this._setOption( "disabled", true ); | |
}, | |
_trigger: function( type, event, data ) { | |
var callback = this.options[ type ]; | |
event = $.Event( event ); | |
event.type = ( type === this.widgetEventPrefix ? | |
type : | |
this.widgetEventPrefix + type ).toLowerCase(); | |
data = data || {}; | |
// copy original event properties over to the new event | |
// this would happen if we could call $.event.fix instead of $.Event | |
// but we don't have a way to force an event to be fixed multiple times | |
if ( event.originalEvent ) { | |
for ( var i = $.event.props.length, prop; i; ) { | |
prop = $.event.props[ --i ]; | |
event[ prop ] = event.originalEvent[ prop ]; | |
} | |
} | |
this.element.trigger( event, data ); | |
return !( $.isFunction(callback) && | |
callback.call( this.element[0], event, data ) === false || | |
event.isDefaultPrevented() ); | |
} | |
}; | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : widget factory extentions for mobile | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.widget", { | |
// decorate the parent _createWidget to trigger `widgetinit` for users | |
// who wish to do post post `widgetcreate` alterations/additions | |
// | |
// TODO create a pull request for jquery ui to trigger this event | |
// in the original _createWidget | |
_createWidget: function() { | |
$.Widget.prototype._createWidget.apply( this, arguments ); | |
this._trigger( 'init' ); | |
}, | |
_getCreateOptions: function() { | |
var elem = this.element, | |
options = {}; | |
$.each( this.options, function( option ) { | |
var value = elem.jqmData( option.replace( /[A-Z]/g, function( c ) { | |
return "-" + c.toLowerCase(); | |
}) | |
); | |
if ( value !== undefined ) { | |
options[ option ] = value; | |
} | |
}); | |
return options; | |
} | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : a workaround for window.matchMedia | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
var $window = $( window ), | |
$html = $( "html" ); | |
/* $.mobile.media method: pass a CSS media type or query and get a bool return | |
note: this feature relies on actual media query support for media queries, though types will work most anywhere | |
examples: | |
$.mobile.media('screen') //>> tests for screen media type | |
$.mobile.media('screen and (min-width: 480px)') //>> tests for screen media type with window width > 480px | |
$.mobile.media('@media screen and (-webkit-min-device-pixel-ratio: 2)') //>> tests for webkit 2x pixel ratio (iPhone 4) | |
*/ | |
$.mobile.media = (function() { | |
// TODO: use window.matchMedia once at least one UA implements it | |
var cache = {}, | |
testDiv = $( "<div id='jquery-mediatest'>" ), | |
fakeBody = $( "<body>" ).append( testDiv ); | |
return function( query ) { | |
if ( !( query in cache ) ) { | |
var styleBlock = document.createElement( "style" ), | |
cssrule = "@media " + query + " { #jquery-mediatest { position:absolute; } }"; | |
//must set type for IE! | |
styleBlock.type = "text/css"; | |
if ( styleBlock.styleSheet ){ | |
styleBlock.styleSheet.cssText = cssrule; | |
} else { | |
styleBlock.appendChild( document.createTextNode(cssrule) ); | |
} | |
$html.prepend( fakeBody ).prepend( styleBlock ); | |
cache[ query ] = testDiv.css( "position" ) === "absolute"; | |
fakeBody.add( styleBlock ).remove(); | |
} | |
return cache[ query ]; | |
}; | |
})(); | |
})(jQuery);/* | |
* jQuery Mobile Framework : support tests | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
(function( $, undefined ) { | |
var fakeBody = $( "<body>" ).prependTo( "html" ), | |
fbCSS = fakeBody[ 0 ].style, | |
vendors = [ "Webkit", "Moz", "O" ], | |
webos = "palmGetResource" in window, //only used to rule out scrollTop | |
bb = window.blackberry; //only used to rule out box shadow, as it's filled opaque on BB | |
// thx Modernizr | |
function propExists( prop ) { | |
var uc_prop = prop.charAt( 0 ).toUpperCase() + prop.substr( 1 ), | |
props = ( prop + " " + vendors.join( uc_prop + " " ) + uc_prop ).split( " " ); | |
for ( var v in props ){ | |
if ( fbCSS[ props[ v ] ] !== undefined ) { | |
return true; | |
} | |
} | |
} | |
// Test for dynamic-updating base tag support ( allows us to avoid href,src attr rewriting ) | |
function baseTagTest() { | |
var fauxBase = location.protocol + "//" + location.host + location.pathname + "ui-dir/", | |
base = $( "head base" ), | |
fauxEle = null, | |
href = "", | |
link, rebase; | |
if ( !base.length ) { | |
base = fauxEle = $( "<base>", { "href": fauxBase }).appendTo( "head" ); | |
} else { | |
href = base.attr( "href" ); | |
} | |
link = $( "<a href='testurl'></a>" ).prependTo( fakeBody ); | |
rebase = link[ 0 ].href; | |
base[ 0 ].href = href ? href : location.pathname; | |
if ( fauxEle ) { | |
fauxEle.remove(); | |
} | |
return rebase.indexOf( fauxBase ) === 0; | |
} | |
// non-UA-based IE version check by James Padolsey, modified by jdalton - from http://gist.github.com/527683 | |
// allows for inclusion of IE 6+, including Windows Mobile 7 | |
$.mobile.browser = {}; | |
$.mobile.browser.ie = (function() { | |
var v = 3, | |
div = document.createElement( "div" ), | |
a = div.all || []; | |
while ( div.innerHTML = "<!--[if gt IE " + ( ++v ) + "]><br><![endif]-->", a[ 0 ] ); | |
return v > 4 ? v : !v; | |
})(); | |
$.extend( $.support, { | |
orientation: "orientation" in window, | |
touch: "ontouchend" in document, | |
cssTransitions: "WebKitTransitionEvent" in window, | |
pushState: "pushState" in history && "replaceState" in history, | |
mediaquery: $.mobile.media( "only all" ), | |
cssPseudoElement: !!propExists( "content" ), | |
touchOverflow: !!propExists( "overflowScrolling" ), | |
boxShadow: !!propExists( "boxShadow" ) && !bb, | |
scrollTop: ( "pageXOffset" in window || "scrollTop" in document.documentElement || "scrollTop" in fakeBody[ 0 ] ) && !webos, | |
dynamicBaseTag: baseTagTest() | |
}); | |
fakeBody.remove(); | |
// $.mobile.ajaxBlacklist is used to override ajaxEnabled on platforms that have known conflicts with hash history updates (BB5, Symbian) | |
// or that generally work better browsing in regular http for full page refreshes (Opera Mini) | |
// Note: This detection below is used as a last resort. | |
// We recommend only using these detection methods when all other more reliable/forward-looking approaches are not possible | |
var nokiaLTE7_3 = (function(){ | |
var ua = window.navigator.userAgent; | |
//The following is an attempt to match Nokia browsers that are running Symbian/s60, with webkit, version 7.3 or older | |
return ua.indexOf( "Nokia" ) > -1 && | |
( ua.indexOf( "Symbian/3" ) > -1 || ua.indexOf( "Series60/5" ) > -1 ) && | |
ua.indexOf( "AppleWebKit" ) > -1 && | |
ua.match( /(BrowserNG|NokiaBrowser)\/7\.[0-3]/ ); | |
})(); | |
$.mobile.ajaxBlacklist = | |
// BlackBerry browsers, pre-webkit | |
window.blackberry && !window.WebKitPoint || | |
// Opera Mini | |
window.operamini && Object.prototype.toString.call( window.operamini ) === "[object OperaMini]" || | |
// Symbian webkits pre 7.3 | |
nokiaLTE7_3; | |
// Lastly, this workaround is the only way we've found so far to get pre 7.3 Symbian webkit devices | |
// to render the stylesheets when they're referenced before this script, as we'd recommend doing. | |
// This simply reappends the CSS in place, which for some reason makes it apply | |
if ( nokiaLTE7_3 ) { | |
$(function() { | |
$( "head link[rel=stylesheet]" ).attr( "rel", "alternate stylesheet" ).attr( "rel", "stylesheet" ); | |
}); | |
} | |
// For ruling out shadows via css | |
if ( !$.support.boxShadow ) { | |
$( "html" ).addClass( "ui-mobile-nosupport-boxshadow" ); | |
} | |
})( jQuery );/* | |
* jQuery Mobile Framework : "mouse" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
// This plugin is an experiment for abstracting away the touch and mouse | |
// events so that developers don't have to worry about which method of input | |
// the device their document is loaded on supports. | |
// | |
// The idea here is to allow the developer to register listeners for the | |
// basic mouse events, such as mousedown, mousemove, mouseup, and click, | |
// and the plugin will take care of registering the correct listeners | |
// behind the scenes to invoke the listener at the fastest possible time | |
// for that device, while still retaining the order of event firing in | |
// the traditional mouse environment, should multiple handlers be registered | |
// on the same element for different events. | |
// | |
// The current version exposes the following virtual events to jQuery bind methods: | |
// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" | |
(function( $, window, document, undefined ) { | |
var dataPropertyName = "virtualMouseBindings", | |
touchTargetPropertyName = "virtualTouchID", | |
virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), | |
touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), | |
activeDocHandlers = {}, | |
resetTimerID = 0, | |
startX = 0, | |
startY = 0, | |
didScroll = false, | |
clickBlockList = [], | |
blockMouseTriggers = false, | |
blockTouchTriggers = false, | |
eventCaptureSupported = "addEventListener" in document, | |
$document = $( document ), | |
nextTouchID = 1, | |
lastTouchID = 0; | |
$.vmouse = { | |
moveDistanceThreshold: 10, | |
clickDistanceThreshold: 10, | |
resetTimerDuration: 1500 | |
}; | |
function getNativeEvent( event ) { | |
while ( event && typeof event.originalEvent !== "undefined" ) { | |
event = event.originalEvent; | |
} | |
return event; | |
} | |
function createVirtualEvent( event, eventType ) { | |
var t = event.type, | |
oe, props, ne, prop, ct, touch, i, j; | |
event = $.Event(event); | |
event.type = eventType; | |
oe = event.originalEvent; | |
props = $.event.props; | |
// copy original event properties over to the new event | |
// this would happen if we could call $.event.fix instead of $.Event | |
// but we don't have a way to force an event to be fixed multiple times | |
if ( oe ) { | |
for ( i = props.length, prop; i; ) { | |
prop = props[ --i ]; | |
event[ prop ] = oe[ prop ]; | |
} | |
} | |
// make sure that if the mouse and click virtual events are generated | |
// without a .which one is defined | |
if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ){ | |
event.which = 1; | |
} | |
if ( t.search(/^touch/) !== -1 ) { | |
ne = getNativeEvent( oe ); | |
t = ne.touches; | |
ct = ne.changedTouches; | |
touch = ( t && t.length ) ? t[0] : ( (ct && ct.length) ? ct[ 0 ] : undefined ); | |
if ( touch ) { | |
for ( j = 0, len = touchEventProps.length; j < len; j++){ | |
prop = touchEventProps[ j ]; | |
event[ prop ] = touch[ prop ]; | |
} | |
} | |
} | |
return event; | |
} | |
function getVirtualBindingFlags( element ) { | |
var flags = {}, | |
b, k; | |
while ( element ) { | |
b = $.data( element, dataPropertyName ); | |
for ( k in b ) { | |
if ( b[ k ] ) { | |
flags[ k ] = flags.hasVirtualBinding = true; | |
} | |
} | |
element = element.parentNode; | |
} | |
return flags; | |
} | |
function getClosestElementWithVirtualBinding( element, eventType ) { | |
var b; | |
while ( element ) { | |
b = $.data( element, dataPropertyName ); | |
if ( b && ( !eventType || b[ eventType ] ) ) { | |
return element; | |
} | |
element = element.parentNode; | |
} | |
return null; | |
} | |
function enableTouchBindings() { | |
blockTouchTriggers = false; | |
} | |
function disableTouchBindings() { | |
blockTouchTriggers = true; | |
} | |
function enableMouseBindings() { | |
lastTouchID = 0; | |
clickBlockList.length = 0; | |
blockMouseTriggers = false; | |
// When mouse bindings are enabled, our | |
// touch bindings are disabled. | |
disableTouchBindings(); | |
} | |
function disableMouseBindings() { | |
// When mouse bindings are disabled, our | |
// touch bindings are enabled. | |
enableTouchBindings(); | |
} | |
function startResetTimer() { | |
clearResetTimer(); | |
resetTimerID = setTimeout(function(){ | |
resetTimerID = 0; | |
enableMouseBindings(); | |
}, $.vmouse.resetTimerDuration ); | |
} | |
function clearResetTimer() { | |
if ( resetTimerID ){ | |
clearTimeout( resetTimerID ); | |
resetTimerID = 0; | |
} | |
} | |
function triggerVirtualEvent( eventType, event, flags ) { | |
var ve; | |
if ( ( flags && flags[ eventType ] ) || | |
( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { | |
ve = createVirtualEvent( event, eventType ); | |
$( event.target).trigger( ve ); | |
} | |
return ve; | |
} | |
function mouseEventCallback( event ) { | |
var touchID = $.data(event.target, touchTargetPropertyName); | |
if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ){ | |
var ve = triggerVirtualEvent( "v" + event.type, event ); | |
if ( ve ) { | |
if ( ve.isDefaultPrevented() ) { | |
event.preventDefault(); | |
} | |
if ( ve.isPropagationStopped() ) { | |
event.stopPropagation(); | |
} | |
if ( ve.isImmediatePropagationStopped() ) { | |
event.stopImmediatePropagation(); | |
} | |
} | |
} | |
} | |
function handleTouchStart( event ) { | |
var touches = getNativeEvent( event ).touches, | |
target, flags; | |
if ( touches && touches.length === 1 ) { | |
target = event.target; | |
flags = getVirtualBindingFlags( target ); | |
if ( flags.hasVirtualBinding ) { | |
lastTouchID = nextTouchID++; | |
$.data( target, touchTargetPropertyName, lastTouchID ); | |
clearResetTimer(); | |
disableMouseBindings(); | |
didScroll = false; | |
var t = getNativeEvent( event ).touches[ 0 ]; | |
startX = t.pageX; | |
startY = t.pageY; | |
triggerVirtualEvent( "vmouseover", event, flags ); | |
triggerVirtualEvent( "vmousedown", event, flags ); | |
} | |
} | |
} | |
function handleScroll( event ) { | |
if ( blockTouchTriggers ) { | |
return; | |
} | |
if ( !didScroll ) { | |
triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); | |
} | |
didScroll = true; | |
startResetTimer(); | |
} | |
function handleTouchMove( event ) { | |
if ( blockTouchTriggers ) { | |
return; | |
} | |
var t = getNativeEvent( event ).touches[ 0 ], | |
didCancel = didScroll, | |
moveThreshold = $.vmouse.moveDistanceThreshold; | |
didScroll = didScroll || | |
( Math.abs(t.pageX - startX) > moveThreshold || | |
Math.abs(t.pageY - startY) > moveThreshold ), | |
flags = getVirtualBindingFlags( event.target ); | |
if ( didScroll && !didCancel ) { | |
triggerVirtualEvent( "vmousecancel", event, flags ); | |
} | |
triggerVirtualEvent( "vmousemove", event, flags ); | |
startResetTimer(); | |
} | |
function handleTouchEnd( event ) { | |
if ( blockTouchTriggers ) { | |
return; | |
} | |
disableTouchBindings(); | |
var flags = getVirtualBindingFlags( event.target ), | |
t; | |
triggerVirtualEvent( "vmouseup", event, flags ); | |
if ( !didScroll ) { | |
var ve = triggerVirtualEvent( "vclick", event, flags ); | |
if ( ve && ve.isDefaultPrevented() ) { | |
// The target of the mouse events that follow the touchend | |
// event don't necessarily match the target used during the | |
// touch. This means we need to rely on coordinates for blocking | |
// any click that is generated. | |
t = getNativeEvent( event ).changedTouches[ 0 ]; | |
clickBlockList.push({ | |
touchID: lastTouchID, | |
x: t.clientX, | |
y: t.clientY | |
}); | |
// Prevent any mouse events that follow from triggering | |
// virtual event notifications. | |
blockMouseTriggers = true; | |
} | |
} | |
triggerVirtualEvent( "vmouseout", event, flags); | |
didScroll = false; | |
startResetTimer(); | |
} | |
function hasVirtualBindings( ele ) { | |
var bindings = $.data( ele, dataPropertyName ), | |
k; | |
if ( bindings ) { | |
for ( k in bindings ) { | |
if ( bindings[ k ] ) { | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
function dummyMouseHandler(){} | |
function getSpecialEventObject( eventType ) { | |
var realType = eventType.substr( 1 ); | |
return { | |
setup: function( data, namespace ) { | |
// If this is the first virtual mouse binding for this element, | |
// add a bindings object to its data. | |
if ( !hasVirtualBindings( this ) ) { | |
$.data( this, dataPropertyName, {}); | |
} | |
// If setup is called, we know it is the first binding for this | |
// eventType, so initialize the count for the eventType to zero. | |
var bindings = $.data( this, dataPropertyName ); | |
bindings[ eventType ] = true; | |
// If this is the first virtual mouse event for this type, | |
// register a global handler on the document. | |
activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; | |
if ( activeDocHandlers[ eventType ] === 1 ) { | |
$document.bind( realType, mouseEventCallback ); | |
} | |
// Some browsers, like Opera Mini, won't dispatch mouse/click events | |
// for elements unless they actually have handlers registered on them. | |
// To get around this, we register dummy handlers on the elements. | |
$( this ).bind( realType, dummyMouseHandler ); | |
// For now, if event capture is not supported, we rely on mouse handlers. | |
if ( eventCaptureSupported ) { | |
// If this is the first virtual mouse binding for the document, | |
// register our touchstart handler on the document. | |
activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; | |
if (activeDocHandlers[ "touchstart" ] === 1) { | |
$document.bind( "touchstart", handleTouchStart ) | |
.bind( "touchend", handleTouchEnd ) | |
// On touch platforms, touching the screen and then dragging your finger | |
// causes the window content to scroll after some distance threshold is | |
// exceeded. On these platforms, a scroll prevents a click event from being | |
// dispatched, and on some platforms, even the touchend is suppressed. To | |
// mimic the suppression of the click event, we need to watch for a scroll | |
// event. Unfortunately, some platforms like iOS don't dispatch scroll | |
// events until *AFTER* the user lifts their finger (touchend). This means | |
// we need to watch both scroll and touchmove events to figure out whether | |
// or not a scroll happenens before the touchend event is fired. | |
.bind( "touchmove", handleTouchMove ) | |
.bind( "scroll", handleScroll ); | |
} | |
} | |
}, | |
teardown: function( data, namespace ) { | |
// If this is the last virtual binding for this eventType, | |
// remove its global handler from the document. | |
--activeDocHandlers[ eventType ]; | |
if ( !activeDocHandlers[ eventType ] ) { | |
$document.unbind( realType, mouseEventCallback ); | |
} | |
if ( eventCaptureSupported ) { | |
// If this is the last virtual mouse binding in existence, | |
// remove our document touchstart listener. | |
--activeDocHandlers[ "touchstart" ]; | |
if ( !activeDocHandlers[ "touchstart" ] ) { | |
$document.unbind( "touchstart", handleTouchStart ) | |
.unbind( "touchmove", handleTouchMove ) | |
.unbind( "touchend", handleTouchEnd ) | |
.unbind( "scroll", handleScroll ); | |
} | |
} | |
var $this = $( this ), | |
bindings = $.data( this, dataPropertyName ); | |
// teardown may be called when an element was | |
// removed from the DOM. If this is the case, | |
// jQuery core may have already stripped the element | |
// of any data bindings so we need to check it before | |
// using it. | |
if ( bindings ) { | |
bindings[ eventType ] = false; | |
} | |
// Unregister the dummy event handler. | |
$this.unbind( realType, dummyMouseHandler ); | |
// If this is the last virtual mouse binding on the | |
// element, remove the binding data from the element. | |
if ( !hasVirtualBindings( this ) ) { | |
$this.removeData( dataPropertyName ); | |
} | |
} | |
}; | |
} | |
// Expose our custom events to the jQuery bind/unbind mechanism. | |
for ( var i = 0; i < virtualEventNames.length; i++ ){ | |
$.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); | |
} | |
// Add a capture click handler to block clicks. | |
// Note that we require event capture support for this so if the device | |
// doesn't support it, we punt for now and rely solely on mouse events. | |
if ( eventCaptureSupported ) { | |
document.addEventListener( "click", function( e ){ | |
var cnt = clickBlockList.length, | |
target = e.target, | |
x, y, ele, i, o, touchID; | |
if ( cnt ) { | |
x = e.clientX; | |
y = e.clientY; | |
threshold = $.vmouse.clickDistanceThreshold; | |
// The idea here is to run through the clickBlockList to see if | |
// the current click event is in the proximity of one of our | |
// vclick events that had preventDefault() called on it. If we find | |
// one, then we block the click. | |
// | |
// Why do we have to rely on proximity? | |
// | |
// Because the target of the touch event that triggered the vclick | |
// can be different from the target of the click event synthesized | |
// by the browser. The target of a mouse/click event that is syntehsized | |
// from a touch event seems to be implementation specific. For example, | |
// some browsers will fire mouse/click events for a link that is near | |
// a touch event, even though the target of the touchstart/touchend event | |
// says the user touched outside the link. Also, it seems that with most | |
// browsers, the target of the mouse/click event is not calculated until the | |
// time it is dispatched, so if you replace an element that you touched | |
// with another element, the target of the mouse/click will be the new | |
// element underneath that point. | |
// | |
// Aside from proximity, we also check to see if the target and any | |
// of its ancestors were the ones that blocked a click. This is necessary | |
// because of the strange mouse/click target calculation done in the | |
// Android 2.1 browser, where if you click on an element, and there is a | |
// mouse/click handler on one of its ancestors, the target will be the | |
// innermost child of the touched element, even if that child is no where | |
// near the point of touch. | |
ele = target; | |
while ( ele ) { | |
for ( i = 0; i < cnt; i++ ) { | |
o = clickBlockList[ i ]; | |
touchID = 0; | |
if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || | |
$.data( ele, touchTargetPropertyName ) === o.touchID ) { | |
// XXX: We may want to consider removing matches from the block list | |
// instead of waiting for the reset timer to fire. | |
e.preventDefault(); | |
e.stopPropagation(); | |
return; | |
} | |
} | |
ele = ele.parentNode; | |
} | |
} | |
}, true); | |
} | |
})( jQuery, window, document ); | |
/* | |
* jQuery Mobile Framework : events | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
// add new event shortcuts | |
$.each( ( "touchstart touchmove touchend orientationchange throttledresize " + | |
"tap taphold swipe swipeleft swiperight scrollstart scrollstop" ).split( " " ), function( i, name ) { | |
$.fn[ name ] = function( fn ) { | |
return fn ? this.bind( name, fn ) : this.trigger( name ); | |
}; | |
$.attrFn[ name ] = true; | |
}); | |
var supportTouch = $.support.touch, | |
scrollEvent = "touchmove scroll", | |
touchStartEvent = supportTouch ? "touchstart" : "mousedown", | |
touchStopEvent = supportTouch ? "touchend" : "mouseup", | |
touchMoveEvent = supportTouch ? "touchmove" : "mousemove"; | |
function triggerCustomEvent( obj, eventType, event ) { | |
var originalType = event.type; | |
event.type = eventType; | |
$.event.handle.call( obj, event ); | |
event.type = originalType; | |
} | |
// also handles scrollstop | |
$.event.special.scrollstart = { | |
enabled: true, | |
setup: function() { | |
var thisObject = this, | |
$this = $( thisObject ), | |
scrolling, | |
timer; | |
function trigger( event, state ) { | |
scrolling = state; | |
triggerCustomEvent( thisObject, scrolling ? "scrollstart" : "scrollstop", event ); | |
} | |
// iPhone triggers scroll after a small delay; use touchmove instead | |
$this.bind( scrollEvent, function( event ) { | |
if ( !$.event.special.scrollstart.enabled ) { | |
return; | |
} | |
if ( !scrolling ) { | |
trigger( event, true ); | |
} | |
clearTimeout( timer ); | |
timer = setTimeout(function() { | |
trigger( event, false ); | |
}, 50 ); | |
}); | |
} | |
}; | |
// also handles taphold | |
$.event.special.tap = { | |
setup: function() { | |
var thisObject = this, | |
$this = $( thisObject ); | |
$this.bind( "vmousedown", function( event ) { | |
if ( event.which && event.which !== 1 ) { | |
return false; | |
} | |
var origTarget = event.target, | |
origEvent = event.originalEvent, | |
timer; | |
function clearTapTimer() { | |
clearTimeout( timer ); | |
} | |
function clearTapHandlers() { | |
clearTapTimer(); | |
$this.unbind( "vclick", clickHandler ) | |
.unbind( "vmouseup", clearTapTimer ) | |
.unbind( "vmousecancel", clearTapHandlers ); | |
} | |
function clickHandler(event) { | |
clearTapHandlers(); | |
// ONLY trigger a 'tap' event if the start target is | |
// the same as the stop target. | |
if ( origTarget == event.target ) { | |
triggerCustomEvent( thisObject, "tap", event ); | |
} | |
} | |
$this.bind( "vmousecancel", clearTapHandlers ) | |
.bind( "vmouseup", clearTapTimer ) | |
.bind( "vclick", clickHandler ); | |
timer = setTimeout(function() { | |
triggerCustomEvent( thisObject, "taphold", $.Event( "taphold" ) ); | |
}, 750 ); | |
}); | |
} | |
}; | |
// also handles swipeleft, swiperight | |
$.event.special.swipe = { | |
scrollSupressionThreshold: 10, // More than this horizontal displacement, and we will suppress scrolling. | |
durationThreshold: 1000, // More time than this, and it isn't a swipe. | |
horizontalDistanceThreshold: 30, // Swipe horizontal displacement must be more than this. | |
verticalDistanceThreshold: 75, // Swipe vertical displacement must be less than this. | |
setup: function() { | |
var thisObject = this, | |
$this = $( thisObject ); | |
$this.bind( touchStartEvent, function( event ) { | |
var data = event.originalEvent.touches ? | |
event.originalEvent.touches[ 0 ] : event, | |
start = { | |
time: ( new Date() ).getTime(), | |
coords: [ data.pageX, data.pageY ], | |
origin: $( event.target ) | |
}, | |
stop; | |
function moveHandler( event ) { | |
if ( !start ) { | |
return; | |
} | |
var data = event.originalEvent.touches ? | |
event.originalEvent.touches[ 0 ] : event; | |
stop = { | |
time: ( new Date() ).getTime(), | |
coords: [ data.pageX, data.pageY ] | |
}; | |
// prevent scrolling | |
if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) { | |
event.preventDefault(); | |
} | |
} | |
$this.bind( touchMoveEvent, moveHandler ) | |
.one( touchStopEvent, function( event ) { | |
$this.unbind( touchMoveEvent, moveHandler ); | |
if ( start && stop ) { | |
if ( stop.time - start.time < $.event.special.swipe.durationThreshold && | |
Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold && | |
Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) { | |
start.origin.trigger( "swipe" ) | |
.trigger( start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight" ); | |
} | |
} | |
start = stop = undefined; | |
}); | |
}); | |
} | |
}; | |
(function( $, window ) { | |
// "Cowboy" Ben Alman | |
var win = $( window ), | |
special_event, | |
get_orientation, | |
last_orientation; | |
$.event.special.orientationchange = special_event = { | |
setup: function() { | |
// If the event is supported natively, return false so that jQuery | |
// will bind to the event using DOM methods. | |
if ( $.support.orientation ) { | |
return false; | |
} | |
// Get the current orientation to avoid initial double-triggering. | |
last_orientation = get_orientation(); | |
// Because the orientationchange event doesn't exist, simulate the | |
// event by testing window dimensions on resize. | |
win.bind( "throttledresize", handler ); | |
}, | |
teardown: function(){ | |
// If the event is not supported natively, return false so that | |
// jQuery will unbind the event using DOM methods. | |
if ( $.support.orientation ) { | |
return false; | |
} | |
// Because the orientationchange event doesn't exist, unbind the | |
// resize event handler. | |
win.unbind( "throttledresize", handler ); | |
}, | |
add: function( handleObj ) { | |
// Save a reference to the bound event handler. | |
var old_handler = handleObj.handler; | |
handleObj.handler = function( event ) { | |
// Modify event object, adding the .orientation property. | |
event.orientation = get_orientation(); | |
// Call the originally-bound event handler and return its result. | |
return old_handler.apply( this, arguments ); | |
}; | |
} | |
}; | |
// If the event is not supported natively, this handler will be bound to | |
// the window resize event to simulate the orientationchange event. | |
function handler() { | |
// Get the current orientation. | |
var orientation = get_orientation(); | |
if ( orientation !== last_orientation ) { | |
// The orientation has changed, so trigger the orientationchange event. | |
last_orientation = orientation; | |
win.trigger( "orientationchange" ); | |
} | |
}; | |
// Get the current page orientation. This method is exposed publicly, should it | |
// be needed, as jQuery.event.special.orientationchange.orientation() | |
$.event.special.orientationchange.orientation = get_orientation = function() { | |
var elem = document.documentElement; | |
return elem && elem.clientWidth / elem.clientHeight < 1.1 ? "portrait" : "landscape"; | |
}; | |
})( jQuery, window ); | |
// throttled resize event | |
(function() { | |
$.event.special.throttledresize = { | |
setup: function() { | |
$( this ).bind( "resize", handler ); | |
}, | |
teardown: function(){ | |
$( this ).unbind( "resize", handler ); | |
} | |
}; | |
var throttle = 250, | |
handler = function() { | |
curr = ( new Date() ).getTime(); | |
diff = curr - lastCall; | |
if ( diff >= throttle ) { | |
lastCall = curr; | |
$( this ).trigger( "throttledresize" ); | |
} else { | |
if ( heldCall ) { | |
clearTimeout( heldCall ); | |
} | |
// Promise a held call will still execute | |
heldCall = setTimeout( handler, throttle - diff ); | |
} | |
}, | |
lastCall = 0, | |
heldCall, | |
curr, | |
diff; | |
})(); | |
$.each({ | |
scrollstop: "scrollstart", | |
taphold: "tap", | |
swipeleft: "swipe", | |
swiperight: "swipe" | |
}, function( event, sourceEvent ) { | |
$.event.special[ event ] = { | |
setup: function() { | |
$( this ).bind( sourceEvent, $.noop ); | |
} | |
}; | |
}); | |
})( jQuery, this ); | |
/*! | |
* jQuery hashchange event - v1.3 - 7/21/2010 | |
* http://benalman.com/projects/jquery-hashchange-plugin/ | |
* | |
* Copyright (c) 2010 "Cowboy" Ben Alman | |
* Dual licensed under the MIT and GPL licenses. | |
* http://benalman.com/about/license/ | |
*/ | |
// Script: jQuery hashchange event | |
// | |
// *Version: 1.3, Last updated: 7/21/2010* | |
// | |
// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/ | |
// GitHub - http://github.com/cowboy/jquery-hashchange/ | |
// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js | |
// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped) | |
// | |
// About: License | |
// | |
// Copyright (c) 2010 "Cowboy" Ben Alman, | |
// Dual licensed under the MIT and GPL licenses. | |
// http://benalman.com/about/license/ | |
// | |
// About: Examples | |
// | |
// These working examples, complete with fully commented code, illustrate a few | |
// ways in which this plugin can be used. | |
// | |
// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/ | |
// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/ | |
// | |
// About: Support and Testing | |
// | |
// Information about what version or versions of jQuery this plugin has been | |
// tested with, what browsers it has been tested in, and where the unit tests | |
// reside (so you can test it yourself). | |
// | |
// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2 | |
// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5, | |
// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5. | |
// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/ | |
// | |
// About: Known issues | |
// | |
// While this jQuery hashchange event implementation is quite stable and | |
// robust, there are a few unfortunate browser bugs surrounding expected | |
// hashchange event-based behaviors, independent of any JavaScript | |
// window.onhashchange abstraction. See the following examples for more | |
// information: | |
// | |
// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/ | |
// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/ | |
// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/ | |
// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/ | |
// | |
// Also note that should a browser natively support the window.onhashchange | |
// event, but not report that it does, the fallback polling loop will be used. | |
// | |
// About: Release History | |
// | |
// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more | |
// "removable" for mobile-only development. Added IE6/7 document.title | |
// support. Attempted to make Iframe as hidden as possible by using | |
// techniques from http://www.paciellogroup.com/blog/?p=604. Added | |
// support for the "shortcut" format $(window).hashchange( fn ) and | |
// $(window).hashchange() like jQuery provides for built-in events. | |
// Renamed jQuery.hashchangeDelay to <jQuery.fn.hashchange.delay> and | |
// lowered its default value to 50. Added <jQuery.fn.hashchange.domain> | |
// and <jQuery.fn.hashchange.src> properties plus document-domain.html | |
// file to address access denied issues when setting document.domain in | |
// IE6/7. | |
// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin | |
// from a page on another domain would cause an error in Safari 4. Also, | |
// IE6/7 Iframe is now inserted after the body (this actually works), | |
// which prevents the page from scrolling when the event is first bound. | |
// Event can also now be bound before DOM ready, but it won't be usable | |
// before then in IE6/7. | |
// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug | |
// where browser version is incorrectly reported as 8.0, despite | |
// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag. | |
// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special | |
// window.onhashchange functionality into a separate plugin for users | |
// who want just the basic event & back button support, without all the | |
// extra awesomeness that BBQ provides. This plugin will be included as | |
// part of jQuery BBQ, but also be available separately. | |
(function($,window,undefined){ | |
'$:nomunge'; // Used by YUI compressor. | |
// Reused string. | |
var str_hashchange = 'hashchange', | |
// Method / object references. | |
doc = document, | |
fake_onhashchange, | |
special = $.event.special, | |
// Does the browser support window.onhashchange? Note that IE8 running in | |
// IE7 compatibility mode reports true for 'onhashchange' in window, even | |
// though the event isn't supported, so also test document.documentMode. | |
doc_mode = doc.documentMode, | |
supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); | |
// Get location.hash (or what you'd expect location.hash to be) sans any | |
// leading #. Thanks for making this necessary, Firefox! | |
function get_fragment( url ) { | |
url = url || location.href; | |
return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' ); | |
}; | |
// Method: jQuery.fn.hashchange | |
// | |
// Bind a handler to the window.onhashchange event or trigger all bound | |
// window.onhashchange event handlers. This behavior is consistent with | |
// jQuery's built-in event handlers. | |
// | |
// Usage: | |
// | |
// > jQuery(window).hashchange( [ handler ] ); | |
// | |
// Arguments: | |
// | |
// handler - (Function) Optional handler to be bound to the hashchange | |
// event. This is a "shortcut" for the more verbose form: | |
// jQuery(window).bind( 'hashchange', handler ). If handler is omitted, | |
// all bound window.onhashchange event handlers will be triggered. This | |
// is a shortcut for the more verbose | |
// jQuery(window).trigger( 'hashchange' ). These forms are described in | |
// the <hashchange event> section. | |
// | |
// Returns: | |
// | |
// (jQuery) The initial jQuery collection of elements. | |
// Allow the "shortcut" format $(elem).hashchange( fn ) for binding and | |
// $(elem).hashchange() for triggering, like jQuery does for built-in events. | |
$.fn[ str_hashchange ] = function( fn ) { | |
return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange ); | |
}; | |
// Property: jQuery.fn.hashchange.delay | |
// | |
// The numeric interval (in milliseconds) at which the <hashchange event> | |
// polling loop executes. Defaults to 50. | |
// Property: jQuery.fn.hashchange.domain | |
// | |
// If you're setting document.domain in your JavaScript, and you want hash | |
// history to work in IE6/7, not only must this property be set, but you must | |
// also set document.domain BEFORE jQuery is loaded into the page. This | |
// property is only applicable if you are supporting IE6/7 (or IE8 operating | |
// in "IE7 compatibility" mode). | |
// | |
// In addition, the <jQuery.fn.hashchange.src> property must be set to the | |
// path of the included "document-domain.html" file, which can be renamed or | |
// modified if necessary (note that the document.domain specified must be the | |
// same in both your main JavaScript as well as in this file). | |
// | |
// Usage: | |
// | |
// jQuery.fn.hashchange.domain = document.domain; | |
// Property: jQuery.fn.hashchange.src | |
// | |
// If, for some reason, you need to specify an Iframe src file (for example, | |
// when setting document.domain as in <jQuery.fn.hashchange.domain>), you can | |
// do so using this property. Note that when using this property, history | |
// won't be recorded in IE6/7 until the Iframe src file loads. This property | |
// is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7 | |
// compatibility" mode). | |
// | |
// Usage: | |
// | |
// jQuery.fn.hashchange.src = 'path/to/file.html'; | |
$.fn[ str_hashchange ].delay = 50; | |
/* | |
$.fn[ str_hashchange ].domain = null; | |
$.fn[ str_hashchange ].src = null; | |
*/ | |
// Event: hashchange event | |
// | |
// Fired when location.hash changes. In browsers that support it, the native | |
// HTML5 window.onhashchange event is used, otherwise a polling loop is | |
// initialized, running every <jQuery.fn.hashchange.delay> milliseconds to | |
// see if the hash has changed. In IE6/7 (and IE8 operating in "IE7 | |
// compatibility" mode), a hidden Iframe is created to allow the back button | |
// and hash-based history to work. | |
// | |
// Usage as described in <jQuery.fn.hashchange>: | |
// | |
// > // Bind an event handler. | |
// > jQuery(window).hashchange( function(e) { | |
// > var hash = location.hash; | |
// > ... | |
// > }); | |
// > | |
// > // Manually trigger the event handler. | |
// > jQuery(window).hashchange(); | |
// | |
// A more verbose usage that allows for event namespacing: | |
// | |
// > // Bind an event handler. | |
// > jQuery(window).bind( 'hashchange', function(e) { | |
// > var hash = location.hash; | |
// > ... | |
// > }); | |
// > | |
// > // Manually trigger the event handler. | |
// > jQuery(window).trigger( 'hashchange' ); | |
// | |
// Additional Notes: | |
// | |
// * The polling loop and Iframe are not created until at least one handler | |
// is actually bound to the 'hashchange' event. | |
// * If you need the bound handler(s) to execute immediately, in cases where | |
// a location.hash exists on page load, via bookmark or page refresh for | |
// example, use jQuery(window).hashchange() or the more verbose | |
// jQuery(window).trigger( 'hashchange' ). | |
// * The event can be bound before DOM ready, but since it won't be usable | |
// before then in IE6/7 (due to the necessary Iframe), recommended usage is | |
// to bind it inside a DOM ready handler. | |
// Override existing $.event.special.hashchange methods (allowing this plugin | |
// to be defined after jQuery BBQ in BBQ's source code). | |
special[ str_hashchange ] = $.extend( special[ str_hashchange ], { | |
// Called only when the first 'hashchange' event is bound to window. | |
setup: function() { | |
// If window.onhashchange is supported natively, there's nothing to do.. | |
if ( supports_onhashchange ) { return false; } | |
// Otherwise, we need to create our own. And we don't want to call this | |
// until the user binds to the event, just in case they never do, since it | |
// will create a polling loop and possibly even a hidden Iframe. | |
$( fake_onhashchange.start ); | |
}, | |
// Called only when the last 'hashchange' event is unbound from window. | |
teardown: function() { | |
// If window.onhashchange is supported natively, there's nothing to do.. | |
if ( supports_onhashchange ) { return false; } | |
// Otherwise, we need to stop ours (if possible). | |
$( fake_onhashchange.stop ); | |
} | |
}); | |
// fake_onhashchange does all the work of triggering the window.onhashchange | |
// event for browsers that don't natively support it, including creating a | |
// polling loop to watch for hash changes and in IE 6/7 creating a hidden | |
// Iframe to enable back and forward. | |
fake_onhashchange = (function(){ | |
var self = {}, | |
timeout_id, | |
// Remember the initial hash so it doesn't get triggered immediately. | |
last_hash = get_fragment(), | |
fn_retval = function(val){ return val; }, | |
history_set = fn_retval, | |
history_get = fn_retval; | |
// Start the polling loop. | |
self.start = function() { | |
timeout_id || poll(); | |
}; | |
// Stop the polling loop. | |
self.stop = function() { | |
timeout_id && clearTimeout( timeout_id ); | |
timeout_id = undefined; | |
}; | |
// This polling loop checks every $.fn.hashchange.delay milliseconds to see | |
// if location.hash has changed, and triggers the 'hashchange' event on | |
// window when necessary. | |
function poll() { | |
var hash = get_fragment(), | |
history_hash = history_get( last_hash ); | |
if ( hash !== last_hash ) { | |
history_set( last_hash = hash, history_hash ); | |
$(window).trigger( str_hashchange ); | |
} else if ( history_hash !== last_hash ) { | |
location.href = location.href.replace( /#.*/, '' ) + history_hash; | |
} | |
timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay ); | |
}; | |
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv | |
// vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv | |
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv | |
$.browser.msie && !supports_onhashchange && (function(){ | |
// Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8 | |
// when running in "IE7 compatibility" mode. | |
var iframe, | |
iframe_src; | |
// When the event is bound and polling starts in IE 6/7, create a hidden | |
// Iframe for history handling. | |
self.start = function(){ | |
if ( !iframe ) { | |
iframe_src = $.fn[ str_hashchange ].src; | |
iframe_src = iframe_src && iframe_src + get_fragment(); | |
// Create hidden Iframe. Attempt to make Iframe as hidden as possible | |
// by using techniques from http://www.paciellogroup.com/blog/?p=604. | |
iframe = $('<iframe tabindex="-1" title="empty"/>').hide() | |
// When Iframe has completely loaded, initialize the history and | |
// start polling. | |
.one( 'load', function(){ | |
iframe_src || history_set( get_fragment() ); | |
poll(); | |
}) | |
// Load Iframe src if specified, otherwise nothing. | |
.attr( 'src', iframe_src || 'javascript:0' ) | |
// Append Iframe after the end of the body to prevent unnecessary | |
// initial page scrolling (yes, this works). | |
.insertAfter( 'body' )[0].contentWindow; | |
// Whenever `document.title` changes, update the Iframe's title to | |
// prettify the back/next history menu entries. Since IE sometimes | |
// errors with "Unspecified error" the very first time this is set | |
// (yes, very useful) wrap this with a try/catch block. | |
doc.onpropertychange = function(){ | |
try { | |
if ( event.propertyName === 'title' ) { | |
iframe.document.title = doc.title; | |
} | |
} catch(e) {} | |
}; | |
} | |
}; | |
// Override the "stop" method since an IE6/7 Iframe was created. Even | |
// if there are no longer any bound event handlers, the polling loop | |
// is still necessary for back/next to work at all! | |
self.stop = fn_retval; | |
// Get history by looking at the hidden Iframe's location.hash. | |
history_get = function() { | |
return get_fragment( iframe.location.href ); | |
}; | |
// Set a new history item by opening and then closing the Iframe | |
// document, *then* setting its location.hash. If document.domain has | |
// been set, update that as well. | |
history_set = function( hash, history_hash ) { | |
var iframe_doc = iframe.document, | |
domain = $.fn[ str_hashchange ].domain; | |
if ( hash !== history_hash ) { | |
// Update Iframe with any initial `document.title` that might be set. | |
iframe_doc.title = doc.title; | |
// Opening the Iframe's document after it has been closed is what | |
// actually adds a history entry. | |
iframe_doc.open(); | |
// Set document.domain for the Iframe document as well, if necessary. | |
domain && iframe_doc.write( '<script>document.domain="' + domain + '"</script>' ); | |
iframe_doc.close(); | |
// Update the Iframe's hash, for great justice. | |
iframe.location.hash = hash; | |
} | |
}; | |
})(); | |
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
// ^^^^^^^^^^^^^^^^^^^ REMOVE IF NOT SUPPORTING IE6/7/8 ^^^^^^^^^^^^^^^^^^^ | |
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
return self; | |
})(); | |
})(jQuery,this); | |
/* | |
* jQuery Mobile Framework : "page" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.page", $.mobile.widget, { | |
options: { | |
theme: "c", | |
domCache: false | |
}, | |
_create: function() { | |
this._trigger( "beforecreate" ); | |
this.element | |
.attr( "tabindex", "0" ) | |
.addClass( "ui-page ui-body-" + this.options.theme ); | |
} | |
}); | |
})( jQuery ); | |
/*! | |
* jQuery Mobile v@VERSION | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
// jQuery.mobile configurable options | |
$.extend( $.mobile, { | |
// Namespace used framework-wide for data-attrs. Default is no namespace | |
ns: "", | |
// Define the url parameter used for referencing widget-generated sub-pages. | |
// Translates to to example.html&ui-page=subpageIdentifier | |
// hash segment before &ui-page= is used to make Ajax request | |
subPageUrlKey: "ui-page", | |
// Class assigned to page currently in view, and during transitions | |
activePageClass: "ui-page-active", | |
// Class used for "active" button state, from CSS framework | |
activeBtnClass: "ui-btn-active", | |
// Automatically handle clicks and form submissions through Ajax, when same-domain | |
ajaxEnabled: true, | |
// Automatically load and show pages based on location.hash | |
hashListeningEnabled: true, | |
// Set default page transition - 'none' for no transitions | |
defaultPageTransition: "slide", | |
// Minimum scroll distance that will be remembered when returning to a page | |
minScrollBack: 250, | |
// Set default dialog transition - 'none' for no transitions | |
defaultDialogTransition: "pop", | |
// Show loading message during Ajax requests | |
// if false, message will not appear, but loading classes will still be toggled on html el | |
loadingMessage: "loading", | |
// Error response message - appears when an Ajax page request fails | |
pageLoadErrorMessage: "Error Loading Page", | |
//automatically initialize the DOM when it's ready | |
autoInitializePage: true, | |
pushStateEnabled: true, | |
// Support conditions that must be met in order to proceed | |
// default enhanced qualifications are media query support OR IE 7+ | |
gradeA: function(){ | |
return $.support.mediaquery || $.mobile.browser.ie && $.mobile.browser.ie >= 7; | |
}, | |
// TODO might be useful upstream in jquery itself ? | |
keyCode: { | |
ALT: 18, | |
BACKSPACE: 8, | |
CAPS_LOCK: 20, | |
COMMA: 188, | |
COMMAND: 91, | |
COMMAND_LEFT: 91, // COMMAND | |
COMMAND_RIGHT: 93, | |
CONTROL: 17, | |
DELETE: 46, | |
DOWN: 40, | |
END: 35, | |
ENTER: 13, | |
ESCAPE: 27, | |
HOME: 36, | |
INSERT: 45, | |
LEFT: 37, | |
MENU: 93, // COMMAND_RIGHT | |
NUMPAD_ADD: 107, | |
NUMPAD_DECIMAL: 110, | |
NUMPAD_DIVIDE: 111, | |
NUMPAD_ENTER: 108, | |
NUMPAD_MULTIPLY: 106, | |
NUMPAD_SUBTRACT: 109, | |
PAGE_DOWN: 34, | |
PAGE_UP: 33, | |
PERIOD: 190, | |
RIGHT: 39, | |
SHIFT: 16, | |
SPACE: 32, | |
TAB: 9, | |
UP: 38, | |
WINDOWS: 91 // COMMAND | |
}, | |
// Scroll page vertically: scroll to 0 to hide iOS address bar, or pass a Y value | |
silentScroll: function( ypos ) { | |
if ( $.type( ypos ) !== "number" ) { | |
ypos = $.mobile.defaultHomeScroll; | |
} | |
// prevent scrollstart and scrollstop events | |
$.event.special.scrollstart.enabled = false; | |
setTimeout(function() { | |
window.scrollTo( 0, ypos ); | |
$( document ).trigger( "silentscroll", { x: 0, y: ypos }); | |
}, 20 ); | |
setTimeout(function() { | |
$.event.special.scrollstart.enabled = true; | |
}, 150 ); | |
}, | |
// Take a data attribute property, prepend the namespace | |
// and then camel case the attribute string | |
nsNormalize: function( prop ) { | |
if ( !prop ) { | |
return; | |
} | |
return $.camelCase( $.mobile.ns + prop ); | |
} | |
}); | |
// Mobile version of data and removeData and hasData methods | |
// ensures all data is set and retrieved using jQuery Mobile's data namespace | |
$.fn.jqmData = function( prop, value ) { | |
var result; | |
if ( typeof prop != "undefined" ) { | |
result = this.data( prop ? $.mobile.nsNormalize( prop ) : prop, value ); | |
} | |
return result; | |
}; | |
$.jqmData = function( elem, prop, value ) { | |
var result; | |
if ( typeof prop != "undefined" ) { | |
result = $.data( elem, prop ? $.mobile.nsNormalize( prop ) : prop, value ); | |
} | |
return result; | |
}; | |
$.fn.jqmRemoveData = function( prop ) { | |
return this.removeData( $.mobile.nsNormalize( prop ) ); | |
}; | |
$.jqmRemoveData = function( elem, prop ) { | |
return $.removeData( elem, $.mobile.nsNormalize( prop ) ); | |
}; | |
$.fn.removeWithDependents = function() { | |
$.removeWithDependents( this ); | |
}; | |
$.removeWithDependents = function( elem ) { | |
var $elem = $( elem ); | |
( $elem.jqmData('dependents') || $() ).remove(); | |
$elem.remove(); | |
}; | |
$.fn.addDependents = function( newDependents ) { | |
$.addDependents( $(this), newDependents ); | |
}; | |
$.addDependents = function( elem, newDependents ) { | |
var dependents = $(elem).jqmData( 'dependents' ) || $(); | |
$(elem).jqmData( 'dependents', $.merge(dependents, newDependents) ); | |
}; | |
// note that this helper doesn't attempt to handle the callback | |
// or setting of an html elements text, its only purpose is | |
// to return the html encoded version of the text in all cases. (thus the name) | |
$.fn.getEncodedText = function() { | |
return $( "<div/>" ).text( $(this).text() ).html(); | |
}; | |
// Monkey-patching Sizzle to filter the :jqmData selector | |
var oldFind = $.find; | |
$.find = function( selector, context, ret, extra ) { | |
selector = selector.replace(/:jqmData\(([^)]*)\)/g, "[data-" + ( $.mobile.ns || "" ) + "$1]"); | |
return oldFind.call( this, selector, context, ret, extra ); | |
}; | |
$.extend( $.find, oldFind ); | |
$.find.matches = function( expr, set ) { | |
return $.find( expr, null, null, set ); | |
}; | |
$.find.matchesSelector = function( node, expr ) { | |
return $.find( expr, null, null, [ node ] ).length > 0; | |
}; | |
})( jQuery, this ); | |
/* | |
* jQuery Mobile Framework : core utilities for auto ajax navigation, base tag mgmt, | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, undefined ) { | |
//define vars for interal use | |
var $window = $( window ), | |
$html = $( 'html' ), | |
$head = $( 'head' ), | |
//url path helpers for use in relative url management | |
path = { | |
// This scary looking regular expression parses an absolute URL or its relative | |
// variants (protocol, site, document, query, and hash), into the various | |
// components (protocol, host, path, query, fragment, etc that make up the | |
// URL as well as some other commonly used sub-parts. When used with RegExp.exec() | |
// or String.match, it parses the URL into a results array that looks like this: | |
// | |
// [0]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread#msg-content | |
// [1]: http://jblas:password@mycompany.com:8080/mail/inbox?msg=1234&type=unread | |
// [2]: http://jblas:password@mycompany.com:8080/mail/inbox | |
// [3]: http://jblas:password@mycompany.com:8080 | |
// [4]: http: | |
// [5]: // | |
// [6]: jblas:password@mycompany.com:8080 | |
// [7]: jblas:password | |
// [8]: jblas | |
// [9]: password | |
// [10]: mycompany.com:8080 | |
// [11]: mycompany.com | |
// [12]: 8080 | |
// [13]: /mail/inbox | |
// [14]: /mail/ | |
// [15]: inbox | |
// [16]: ?msg=1234&type=unread | |
// [17]: #msg-content | |
// | |
urlParseRE: /^(((([^:\/#\?]+:)?(?:(\/\/)((?:(([^:@\/#\?]+)(?:\:([^:@\/#\?]+))?)@)?(([^:\/#\?\]\[]+|\[[^\/\]@#?]+\])(?:\:([0-9]+))?))?)?)?((\/?(?:[^\/\?#]+\/+)*)([^\?#]*)))?(\?[^#]+)?)(#.*)?/, | |
//Parse a URL into a structure that allows easy access to | |
//all of the URL components by name. | |
parseUrl: function( url ) { | |
// If we're passed an object, we'll assume that it is | |
// a parsed url object and just return it back to the caller. | |
if ( $.type( url ) === "object" ) { | |
return url; | |
} | |
var matches = path.urlParseRE.exec( url || "" ) || []; | |
// Create an object that allows the caller to access the sub-matches | |
// by name. Note that IE returns an empty string instead of undefined, | |
// like all other browsers do, so we normalize everything so its consistent | |
// no matter what browser we're running on. | |
return { | |
href: matches[ 0 ] || "", | |
hrefNoHash: matches[ 1 ] || "", | |
hrefNoSearch: matches[ 2 ] || "", | |
domain: matches[ 3 ] || "", | |
protocol: matches[ 4 ] || "", | |
doubleSlash: matches[ 5 ] || "", | |
authority: matches[ 6 ] || "", | |
username: matches[ 8 ] || "", | |
password: matches[ 9 ] || "", | |
host: matches[ 10 ] || "", | |
hostname: matches[ 11 ] || "", | |
port: matches[ 12 ] || "", | |
pathname: matches[ 13 ] || "", | |
directory: matches[ 14 ] || "", | |
filename: matches[ 15 ] || "", | |
search: matches[ 16 ] || "", | |
hash: matches[ 17 ] || "" | |
}; | |
}, | |
//Turn relPath into an asbolute path. absPath is | |
//an optional absolute path which describes what | |
//relPath is relative to. | |
makePathAbsolute: function( relPath, absPath ) { | |
if ( relPath && relPath.charAt( 0 ) === "/" ) { | |
return relPath; | |
} | |
relPath = relPath || ""; | |
absPath = absPath ? absPath.replace( /^\/|(\/[^\/]*|[^\/]+)$/g, "" ) : ""; | |
var absStack = absPath ? absPath.split( "/" ) : [], | |
relStack = relPath.split( "/" ); | |
for ( var i = 0; i < relStack.length; i++ ) { | |
var d = relStack[ i ]; | |
switch ( d ) { | |
case ".": | |
break; | |
case "..": | |
if ( absStack.length ) { | |
absStack.pop(); | |
} | |
break; | |
default: | |
absStack.push( d ); | |
break; | |
} | |
} | |
return "/" + absStack.join( "/" ); | |
}, | |
//Returns true if both urls have the same domain. | |
isSameDomain: function( absUrl1, absUrl2 ) { | |
return path.parseUrl( absUrl1 ).domain === path.parseUrl( absUrl2 ).domain; | |
}, | |
//Returns true for any relative variant. | |
isRelativeUrl: function( url ) { | |
// All relative Url variants have one thing in common, no protocol. | |
return path.parseUrl( url ).protocol === ""; | |
}, | |
//Returns true for an absolute url. | |
isAbsoluteUrl: function( url ) { | |
return path.parseUrl( url ).protocol !== ""; | |
}, | |
//Turn the specified realtive URL into an absolute one. This function | |
//can handle all relative variants (protocol, site, document, query, fragment). | |
makeUrlAbsolute: function( relUrl, absUrl ) { | |
if ( !path.isRelativeUrl( relUrl ) ) { | |
return relUrl; | |
} | |
var relObj = path.parseUrl( relUrl ), | |
absObj = path.parseUrl( absUrl ), | |
protocol = relObj.protocol || absObj.protocol, | |
doubleSlash = relObj.protocol ? relObj.doubleSlash : ( relObj.doubleSlash || absObj.doubleSlash ); | |
authority = relObj.authority || absObj.authority, | |
hasPath = relObj.pathname !== "", | |
pathname = path.makePathAbsolute( relObj.pathname || absObj.filename, absObj.pathname ), | |
search = relObj.search || ( !hasPath && absObj.search ) || "", | |
hash = relObj.hash; | |
return protocol + doubleSlash + authority + pathname + search + hash; | |
}, | |
//Add search (aka query) params to the specified url. | |
addSearchParams: function( url, params ) { | |
var u = path.parseUrl( url ), | |
p = ( typeof params === "object" ) ? $.param( params ) : params, | |
s = u.search || "?"; | |
return u.hrefNoSearch + s + ( s.charAt( s.length - 1 ) !== "?" ? "&" : "" ) + p + ( u.hash || "" ); | |
}, | |
convertUrlToDataUrl: function( absUrl ) { | |
var u = path.parseUrl( absUrl ); | |
if ( path.isEmbeddedPage( u ) ) { | |
// For embedded pages, remove the dialog hash key as in getFilePath(), | |
// otherwise the Data Url won't match the id of the embedded Page. | |
return u.hash.split( dialogHashKey )[0].replace( /^#/, "" ); | |
} else if ( path.isSameDomain( u, documentBase ) ) { | |
return u.hrefNoHash.replace( documentBase.domain, "" ); | |
} | |
return absUrl; | |
}, | |
//get path from current hash, or from a file path | |
get: function( newPath ) { | |
if( newPath === undefined ) { | |
newPath = location.hash; | |
} | |
return path.stripHash( newPath ).replace( /[^\/]*\.[^\/*]+$/, '' ); | |
}, | |
//return the substring of a filepath before the sub-page key, for making a server request | |
getFilePath: function( path ) { | |
var splitkey = '&' + $.mobile.subPageUrlKey; | |
return path && path.split( splitkey )[0].split( dialogHashKey )[0]; | |
}, | |
//set location hash to path | |
set: function( path ) { | |
location.hash = path; | |
}, | |
//test if a given url (string) is a path | |
//NOTE might be exceptionally naive | |
isPath: function( url ) { | |
return ( /\// ).test( url ); | |
}, | |
//return a url path with the window's location protocol/hostname/pathname removed | |
clean: function( url ) { | |
return url.replace( documentBase.domain, "" ); | |
}, | |
//just return the url without an initial # | |
stripHash: function( url ) { | |
return url.replace( /^#/, "" ); | |
}, | |
//remove the preceding hash, any query params, and dialog notations | |
cleanHash: function( hash ) { | |
return path.stripHash( hash.replace( /\?.*$/, "" ).replace( dialogHashKey, "" ) ); | |
}, | |
//check whether a url is referencing the same domain, or an external domain or different protocol | |
//could be mailto, etc | |
isExternal: function( url ) { | |
var u = path.parseUrl( url ); | |
return u.protocol && u.domain !== documentUrl.domain ? true : false; | |
}, | |
hasProtocol: function( url ) { | |
return ( /^(:?\w+:)/ ).test( url ); | |
}, | |
//check if the specified url refers to the first page in the main application document. | |
isFirstPageUrl: function( url ) { | |
// We only deal with absolute paths. | |
var u = path.parseUrl( path.makeUrlAbsolute( url, documentBase ) ), | |
// Does the url have the same path as the document? | |
samePath = u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ), | |
// Get the first page element. | |
fp = $.mobile.firstPage, | |
// Get the id of the first page element if it has one. | |
fpId = fp && fp[0] ? fp[0].id : undefined; | |
// The url refers to the first page if the path matches the document and | |
// it either has no hash value, or the hash is exactly equal to the id of the | |
// first page element. | |
return samePath && ( !u.hash || u.hash === "#" || ( fpId && u.hash.replace( /^#/, "" ) === fpId ) ); | |
}, | |
isEmbeddedPage: function( url ) { | |
var u = path.parseUrl( url ); | |
//if the path is absolute, then we need to compare the url against | |
//both the documentUrl and the documentBase. The main reason for this | |
//is that links embedded within external documents will refer to the | |
//application document, whereas links embedded within the application | |
//document will be resolved against the document base. | |
if ( u.protocol !== "" ) { | |
return ( u.hash && ( u.hrefNoHash === documentUrl.hrefNoHash || ( documentBaseDiffers && u.hrefNoHash === documentBase.hrefNoHash ) ) ); | |
} | |
return (/^#/).test( u.href ); | |
} | |
}, | |
//will be defined when a link is clicked and given an active class | |
$activeClickedLink = null, | |
//urlHistory is purely here to make guesses at whether the back or forward button was clicked | |
//and provide an appropriate transition | |
urlHistory = { | |
// Array of pages that are visited during a single page load. | |
// Each has a url and optional transition, title, and pageUrl (which represents the file path, in cases where URL is obscured, such as dialogs) | |
stack: [], | |
//maintain an index number for the active page in the stack | |
activeIndex: 0, | |
//get active | |
getActive: function() { | |
return urlHistory.stack[ urlHistory.activeIndex ]; | |
}, | |
getPrev: function() { | |
return urlHistory.stack[ urlHistory.activeIndex - 1 ]; | |
}, | |
getNext: function() { | |
return urlHistory.stack[ urlHistory.activeIndex + 1 ]; | |
}, | |
// addNew is used whenever a new page is added | |
addNew: function( url, transition, title, pageUrl, role ) { | |
//if there's forward history, wipe it | |
if( urlHistory.getNext() ) { | |
urlHistory.clearForward(); | |
} | |
urlHistory.stack.push( {url : url, transition: transition, title: title, pageUrl: pageUrl, role: role } ); | |
urlHistory.activeIndex = urlHistory.stack.length - 1; | |
}, | |
//wipe urls ahead of active index | |
clearForward: function() { | |
urlHistory.stack = urlHistory.stack.slice( 0, urlHistory.activeIndex + 1 ); | |
}, | |
directHashChange: function( opts ) { | |
var back , forward, newActiveIndex, prev = this.getActive(); | |
// check if url isp in history and if it's ahead or behind current page | |
$.each( urlHistory.stack, function( i, historyEntry ) { | |
//if the url is in the stack, it's a forward or a back | |
if( opts.currentUrl === historyEntry.url ) { | |
//define back and forward by whether url is older or newer than current page | |
back = i < urlHistory.activeIndex; | |
forward = !back; | |
newActiveIndex = i; | |
} | |
}); | |
// save new page index, null check to prevent falsey 0 result | |
this.activeIndex = newActiveIndex !== undefined ? newActiveIndex : this.activeIndex; | |
if( back ) { | |
( opts.either || opts.isBack )( true ); | |
} else if( forward ) { | |
( opts.either || opts.isForward )( false ); | |
} | |
}, | |
//disable hashchange event listener internally to ignore one change | |
//toggled internally when location.hash is updated to match the url of a successful page load | |
ignoreNextHashChange: false | |
}, | |
//define first selector to receive focus when a page is shown | |
focusable = "[tabindex],a,button:visible,select:visible,input", | |
//queue to hold simultanious page transitions | |
pageTransitionQueue = [], | |
//indicates whether or not page is in process of transitioning | |
isPageTransitioning = false, | |
//nonsense hash change key for dialogs, so they create a history entry | |
dialogHashKey = "&ui-state=dialog", | |
//existing base tag? | |
$base = $head.children( "base" ), | |
//tuck away the original document URL minus any fragment. | |
documentUrl = path.parseUrl( location.href ), | |
//if the document has an embedded base tag, documentBase is set to its | |
//initial value. If a base tag does not exist, then we default to the documentUrl. | |
documentBase = $base.length ? path.parseUrl( path.makeUrlAbsolute( $base.attr( "href" ), documentUrl.href ) ) : documentUrl, | |
//cache the comparison once. | |
documentBaseDiffers = ( documentUrl.hrefNoHash !== documentBase.hrefNoHash ); | |
//base element management, defined depending on dynamic base tag support | |
var base = $.support.dynamicBaseTag ? { | |
//define base element, for use in routing asset urls that are referenced in Ajax-requested markup | |
element: ( $base.length ? $base : $( "<base>", { href: documentBase.hrefNoHash } ).prependTo( $head ) ), | |
//set the generated BASE element's href attribute to a new page's base path | |
set: function( href ) { | |
base.element.attr( "href", path.makeUrlAbsolute( href, documentBase ) ); | |
}, | |
//set the generated BASE element's href attribute to a new page's base path | |
reset: function() { | |
base.element.attr( "href", documentBase.hrefNoHash ); | |
} | |
} : undefined; | |
/* | |
internal utility functions | |
--------------------------------------*/ | |
//direct focus to the page title, or otherwise first focusable element | |
function reFocus( page ) { | |
var pageTitle = page.find( ".ui-title:eq(0)" ); | |
if( pageTitle.length ) { | |
pageTitle.focus(); | |
} | |
else{ | |
page.focus(); | |
} | |
} | |
//remove active classes after page transition or error | |
function removeActiveLinkClass( forceRemoval ) { | |
if( !!$activeClickedLink && ( !$activeClickedLink.closest( '.ui-page-active' ).length || forceRemoval ) ) { | |
$activeClickedLink.removeClass( $.mobile.activeBtnClass ); | |
} | |
$activeClickedLink = null; | |
} | |
function releasePageTransitionLock() { | |
isPageTransitioning = false; | |
if( pageTransitionQueue.length > 0 ) { | |
$.mobile.changePage.apply( null, pageTransitionQueue.pop() ); | |
} | |
} | |
// Save the last scroll distance per page, before it is hidden | |
var setLastScrollEnabled = true, | |
firstScrollElem, getScrollElem, setLastScroll, delayedSetLastScroll; | |
getScrollElem = function() { | |
var scrollElem = $window, activePage, | |
touchOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled; | |
if( touchOverflow ){ | |
activePage = $( ".ui-page-active" ); | |
scrollElem = activePage.is( ".ui-native-fixed" ) ? activePage.find( ".ui-content" ) : activePage; | |
} | |
return scrollElem; | |
}; | |
setLastScroll = function( scrollElem ) { | |
// this barrier prevents setting the scroll value based on the browser | |
// scrolling the window based on a hashchange | |
if( !setLastScrollEnabled ) { | |
return; | |
} | |
var active = $.mobile.urlHistory.getActive(); | |
if( active ) { | |
var lastScroll = scrollElem && scrollElem.scrollTop(); | |
// Set active page's lastScroll prop. | |
// If the location we're scrolling to is less than minScrollBack, let it go. | |
active.lastScroll = lastScroll < $.mobile.minScrollBack ? $.mobile.defaultHomeScroll : lastScroll; | |
} | |
}; | |
// bind to scrollstop to gather scroll position. The delay allows for the hashchange | |
// event to fire and disable scroll recording in the case where the browser scrolls | |
// to the hash targets location (sometimes the top of the page). once pagechange fires | |
// getLastScroll is again permitted to operate | |
delayedSetLastScroll = function() { | |
setTimeout( setLastScroll, 100, $(this) ); | |
}; | |
// disable an scroll setting when a hashchange has been fired, this only works | |
// because the recording of the scroll position is delayed for 100ms after | |
// the browser might have changed the position because of the hashchange | |
$window.bind( $.support.pushState ? "popstate" : "hashchange", function() { | |
setLastScrollEnabled = false; | |
}); | |
// handle initial hashchange from chrome :( | |
$window.one( $.support.pushState ? "popstate" : "hashchange", function() { | |
setLastScrollEnabled = true; | |
}); | |
// wait until the mobile page container has been determined to bind to pagechange | |
$window.one( "pagecontainercreate", function(){ | |
// once the page has changed, re-enable the scroll recording | |
$.mobile.pageContainer.bind( "pagechange", function() { | |
var scrollElem = getScrollElem(); | |
setLastScrollEnabled = true; | |
// remove any binding that previously existed on the get scroll | |
// which may or may not be different than the scroll element determined for | |
// this page previously | |
scrollElem.unbind( "scrollstop", delayedSetLastScroll ); | |
// determine and bind to the current scoll element which may be the window | |
// or in the case of touch overflow the element with touch overflow | |
scrollElem.bind( "scrollstop", delayedSetLastScroll ); | |
}); | |
}); | |
// bind to scrollstop for the first page as "pagechange" won't be fired in that case | |
getScrollElem().bind( "scrollstop", delayedSetLastScroll ); | |
// Make the iOS clock quick-scroll work again if we're using native overflow scrolling | |
/* | |
if( $.support.touchOverflow ){ | |
if( $.mobile.touchOverflowEnabled ){ | |
$( window ).bind( "scrollstop", function(){ | |
if( $( this ).scrollTop() === 0 ){ | |
$.mobile.activePage.scrollTop( 0 ); | |
} | |
}); | |
} | |
} | |
*/ | |
//function for transitioning between two existing pages | |
function transitionPages( toPage, fromPage, transition, reverse ) { | |
//get current scroll distance | |
var active = $.mobile.urlHistory.getActive(), | |
touchOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled, | |
toScroll = active.lastScroll || ( touchOverflow ? 0 : $.mobile.defaultHomeScroll ), | |
screenHeight = getScreenHeight(); | |
// Scroll to top, hide addr bar | |
window.scrollTo( 0, $.mobile.defaultHomeScroll ); | |
if( fromPage ) { | |
//trigger before show/hide events | |
fromPage.data( "page" )._trigger( "beforehide", null, { nextPage: toPage } ); | |
} | |
if( !touchOverflow){ | |
toPage.height( screenHeight + toScroll ); | |
} | |
toPage.data( "page" )._trigger( "beforeshow", null, { prevPage: fromPage || $( "" ) } ); | |
//clear page loader | |
$.mobile.hidePageLoadingMsg(); | |
if( touchOverflow && toScroll ){ | |
toPage.addClass( "ui-mobile-pre-transition" ); | |
// Send focus to page as it is now display: block | |
reFocus( toPage ); | |
//set page's scrollTop to remembered distance | |
if( toPage.is( ".ui-native-fixed" ) ){ | |
toPage.find( ".ui-content" ).scrollTop( toScroll ); | |
} | |
else{ | |
toPage.scrollTop( toScroll ); | |
} | |
} | |
//find the transition handler for the specified transition. If there | |
//isn't one in our transitionHandlers dictionary, use the default one. | |
//call the handler immediately to kick-off the transition. | |
var th = $.mobile.transitionHandlers[transition || "none"] || $.mobile.defaultTransitionHandler, | |
promise = th( transition, reverse, toPage, fromPage ); | |
promise.done(function() { | |
//reset toPage height back | |
if( !touchOverflow ){ | |
toPage.height( "" ); | |
// Send focus to the newly shown page | |
reFocus( toPage ); | |
} | |
// Jump to top or prev scroll, sometimes on iOS the page has not rendered yet. | |
if( !touchOverflow ){ | |
$.mobile.silentScroll( toScroll ); | |
} | |
//trigger show/hide events | |
if( fromPage ) { | |
if( !touchOverflow ){ | |
fromPage.height( "" ); | |
} | |
fromPage.data( "page" )._trigger( "hide", null, { nextPage: toPage } ); | |
} | |
//trigger pageshow, define prevPage as either fromPage or empty jQuery obj | |
toPage.data( "page" )._trigger( "show", null, { prevPage: fromPage || $( "" ) } ); | |
}); | |
return promise; | |
} | |
//simply set the active page's minimum height to screen height, depending on orientation | |
function getScreenHeight(){ | |
var orientation = jQuery.event.special.orientationchange.orientation(), | |
port = orientation === "portrait", | |
winMin = port ? 480 : 320, | |
screenHeight = port ? screen.availHeight : screen.availWidth, | |
winHeight = Math.max( winMin, $( window ).height() ), | |
pageMin = Math.min( screenHeight, winHeight ); | |
return pageMin; | |
} | |
$.mobile.getScreenHeight = getScreenHeight; | |
//simply set the active page's minimum height to screen height, depending on orientation | |
function resetActivePageHeight(){ | |
// Don't apply this height in touch overflow enabled mode | |
if( $.support.touchOverflow && $.mobile.touchOverflowEnabled ){ | |
return; | |
} | |
$( "." + $.mobile.activePageClass ).css( "min-height", getScreenHeight() ); | |
} | |
//shared page enhancements | |
function enhancePage( $page, role ) { | |
// If a role was specified, make sure the data-role attribute | |
// on the page element is in sync. | |
if( role ) { | |
$page.attr( "data-" + $.mobile.ns + "role", role ); | |
} | |
//run page plugin | |
$page.page(); | |
} | |
/* exposed $.mobile methods */ | |
//animation complete callback | |
$.fn.animationComplete = function( callback ) { | |
if( $.support.cssTransitions ) { | |
return $( this ).one( 'webkitAnimationEnd', callback ); | |
} | |
else{ | |
// defer execution for consistency between webkit/non webkit | |
setTimeout( callback, 0 ); | |
return $( this ); | |
} | |
}; | |
//expose path object on $.mobile | |
$.mobile.path = path; | |
//expose base object on $.mobile | |
$.mobile.base = base; | |
//history stack | |
$.mobile.urlHistory = urlHistory; | |
$.mobile.dialogHashKey = dialogHashKey; | |
//default non-animation transition handler | |
$.mobile.noneTransitionHandler = function( name, reverse, $toPage, $fromPage ) { | |
if ( $fromPage ) { | |
$fromPage.removeClass( $.mobile.activePageClass ); | |
} | |
$toPage.addClass( $.mobile.activePageClass ); | |
return $.Deferred().resolve( name, reverse, $toPage, $fromPage ).promise(); | |
}; | |
//default handler for unknown transitions | |
$.mobile.defaultTransitionHandler = $.mobile.noneTransitionHandler; | |
//transition handler dictionary for 3rd party transitions | |
$.mobile.transitionHandlers = { | |
none: $.mobile.defaultTransitionHandler | |
}; | |
//enable cross-domain page support | |
$.mobile.allowCrossDomainPages = false; | |
//return the original document url | |
$.mobile.getDocumentUrl = function(asParsedObject) { | |
return asParsedObject ? $.extend( {}, documentUrl ) : documentUrl.href; | |
}; | |
//return the original document base url | |
$.mobile.getDocumentBase = function(asParsedObject) { | |
return asParsedObject ? $.extend( {}, documentBase ) : documentBase.href; | |
}; | |
$.mobile._bindPageRemove = function() { | |
var page = $(this); | |
// when dom caching is not enabled or the page is embedded bind to remove the page on hide | |
if( !page.data("page").options.domCache | |
&& page.is(":jqmData(external-page='true')") ) { | |
page.bind( 'pagehide.remove', function() { | |
var $this = $( this ), | |
prEvent = new $.Event( "pageremove" ); | |
$this.trigger( prEvent ); | |
if( !prEvent.isDefaultPrevented() ){ | |
$this.removeWithDependents(); | |
} | |
}); | |
} | |
}; | |
// Load a page into the DOM. | |
$.mobile.loadPage = function( url, options ) { | |
// This function uses deferred notifications to let callers | |
// know when the page is done loading, or if an error has occurred. | |
var deferred = $.Deferred(), | |
// The default loadPage options with overrides specified by | |
// the caller. | |
settings = $.extend( {}, $.mobile.loadPage.defaults, options ), | |
// The DOM element for the page after it has been loaded. | |
page = null, | |
// If the reloadPage option is true, and the page is already | |
// in the DOM, dupCachedPage will be set to the page element | |
// so that it can be removed after the new version of the | |
// page is loaded off the network. | |
dupCachedPage = null, | |
// determine the current base url | |
findBaseWithDefault = function(){ | |
var closestBase = ( $.mobile.activePage && getClosestBaseUrl( $.mobile.activePage ) ); | |
return closestBase || documentBase.hrefNoHash; | |
}, | |
// The absolute version of the URL passed into the function. This | |
// version of the URL may contain dialog/subpage params in it. | |
absUrl = path.makeUrlAbsolute( url, findBaseWithDefault() ); | |
// If the caller provided data, and we're using "get" request, | |
// append the data to the URL. | |
if ( settings.data && settings.type === "get" ) { | |
absUrl = path.addSearchParams( absUrl, settings.data ); | |
settings.data = undefined; | |
} | |
// If the caller is using a "post" request, reloadPage must be true | |
if( settings.data && settings.type === "post" ){ | |
settings.reloadPage = true; | |
} | |
// The absolute version of the URL minus any dialog/subpage params. | |
// In otherwords the real URL of the page to be loaded. | |
var fileUrl = path.getFilePath( absUrl ), | |
// The version of the Url actually stored in the data-url attribute of | |
// the page. For embedded pages, it is just the id of the page. For pages | |
// within the same domain as the document base, it is the site relative | |
// path. For cross-domain pages (Phone Gap only) the entire absolute Url | |
// used to load the page. | |
dataUrl = path.convertUrlToDataUrl( absUrl ); | |
// Make sure we have a pageContainer to work with. | |
settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; | |
// Check to see if the page already exists in the DOM. | |
page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" ); | |
// If we failed to find the page, check to see if the url is a | |
// reference to an embedded page. If so, it may have been dynamically | |
// injected by a developer, in which case it would be lacking a data-url | |
// attribute and in need of enhancement. | |
if ( page.length === 0 && !path.isPath( dataUrl ) ) { | |
page = settings.pageContainer.children( "#" + dataUrl ) | |
.attr( "data-" + $.mobile.ns + "url", dataUrl ) | |
} | |
// If we failed to find a page in the DOM, check the URL to see if it | |
// refers to the first page in the application. | |
if ( page.length === 0 && $.mobile.firstPage && path.isFirstPageUrl( absUrl ) ) { | |
page = $( $.mobile.firstPage ); | |
} | |
// Reset base to the default document base. | |
if ( base ) { | |
base.reset(); | |
} | |
// If the page we are interested in is already in the DOM, | |
// and the caller did not indicate that we should force a | |
// reload of the file, we are done. Otherwise, track the | |
// existing page as a duplicated. | |
if ( page.length ) { | |
if ( !settings.reloadPage ) { | |
enhancePage( page, settings.role ); | |
deferred.resolve( absUrl, options, page ); | |
return deferred.promise(); | |
} | |
dupCachedPage = page; | |
} | |
var mpc = settings.pageContainer, | |
pblEvent = new $.Event( "pagebeforeload" ), | |
triggerData = { url: url, absUrl: absUrl, dataUrl: dataUrl, deferred: deferred, options: settings }; | |
// Let listeners know we're about to load a page. | |
mpc.trigger( pblEvent, triggerData ); | |
// If the default behavior is prevented, stop here! | |
if( pblEvent.isDefaultPrevented() ){ | |
return deferred.promise(); | |
} | |
if ( settings.showLoadMsg ) { | |
// This configurable timeout allows cached pages a brief delay to load without showing a message | |
var loadMsgDelay = setTimeout(function(){ | |
$.mobile.showPageLoadingMsg(); | |
}, settings.loadMsgDelay ), | |
// Shared logic for clearing timeout and removing message. | |
hideMsg = function(){ | |
// Stop message show timer | |
clearTimeout( loadMsgDelay ); | |
// Hide loading message | |
$.mobile.hidePageLoadingMsg(); | |
}; | |
} | |
if ( !( $.mobile.allowCrossDomainPages || path.isSameDomain( documentUrl, absUrl ) ) ) { | |
deferred.reject( absUrl, options ); | |
} else { | |
// Load the new page. | |
$.ajax({ | |
url: fileUrl, | |
type: settings.type, | |
data: settings.data, | |
dataType: "html", | |
success: function( html ) { | |
//pre-parse html to check for a data-url, | |
//use it as the new fileUrl, base path, etc | |
var all = $( "<div></div>" ), | |
//page title regexp | |
newPageTitle = html.match( /<title[^>]*>([^<]*)/ ) && RegExp.$1, | |
// TODO handle dialogs again | |
pageElemRegex = new RegExp( "(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>)" ), | |
dataUrlRegex = new RegExp( "\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?" ); | |
// data-url must be provided for the base tag so resource requests can be directed to the | |
// correct url. loading into a temprorary element makes these requests immediately | |
if( pageElemRegex.test( html ) | |
&& RegExp.$1 | |
&& dataUrlRegex.test( RegExp.$1 ) | |
&& RegExp.$1 ) { | |
url = fileUrl = path.getFilePath( RegExp.$1 ); | |
} | |
if ( base ) { | |
base.set( fileUrl ); | |
} | |
//workaround to allow scripts to execute when included in page divs | |
all.get( 0 ).innerHTML = html; | |
page = all.find( ":jqmData(role='page'), :jqmData(role='dialog')" ).first(); | |
//if page elem couldn't be found, create one and insert the body element's contents | |
if( !page.length ){ | |
page = $( "<div data-" + $.mobile.ns + "role='page'>" + html.split( /<\/?body[^>]*>/gmi )[1] + "</div>" ); | |
} | |
if ( newPageTitle && !page.jqmData( "title" ) ) { | |
page.jqmData( "title", newPageTitle ); | |
} | |
//rewrite src and href attrs to use a base url | |
if( !$.support.dynamicBaseTag ) { | |
var newPath = path.get( fileUrl ); | |
page.find( "[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]" ).each(function() { | |
var thisAttr = $( this ).is( '[href]' ) ? 'href' : | |
$(this).is('[src]') ? 'src' : 'action', | |
thisUrl = $( this ).attr( thisAttr ); | |
// XXX_jblas: We need to fix this so that it removes the document | |
// base URL, and then prepends with the new page URL. | |
//if full path exists and is same, chop it - helps IE out | |
thisUrl = thisUrl.replace( location.protocol + '//' + location.host + location.pathname, '' ); | |
if( !/^(\w+:|#|\/)/.test( thisUrl ) ) { | |
$( this ).attr( thisAttr, newPath + thisUrl ); | |
} | |
}); | |
} | |
//append to page and enhance | |
// TODO taging a page with external to make sure that embedded pages aren't removed | |
// by the various page handling code is bad. Having page handling code in many | |
// places is bad. Solutions post 1.0 | |
page | |
.attr( "data-" + $.mobile.ns + "url", path.convertUrlToDataUrl( fileUrl ) ) | |
.attr( "data-" + $.mobile.ns + "external-page", true ) | |
.appendTo( settings.pageContainer ); | |
// wait for page creation to leverage options defined on widget | |
page.one( 'pagecreate', $.mobile._bindPageRemove ); | |
enhancePage( page, settings.role ); | |
// Enhancing the page may result in new dialogs/sub pages being inserted | |
// into the DOM. If the original absUrl refers to a sub-page, that is the | |
// real page we are interested in. | |
if ( absUrl.indexOf( "&" + $.mobile.subPageUrlKey ) > -1 ) { | |
page = settings.pageContainer.children( ":jqmData(url='" + dataUrl + "')" ); | |
} | |
//bind pageHide to removePage after it's hidden, if the page options specify to do so | |
// Remove loading message. | |
if ( settings.showLoadMsg ) { | |
hideMsg(); | |
} | |
// Add the page reference to our triggerData. | |
triggerData.page = page; | |
// Let listeners know the page loaded successfully. | |
settings.pageContainer.trigger( "pageload", triggerData ); | |
deferred.resolve( absUrl, options, page, dupCachedPage ); | |
}, | |
error: function() { | |
//set base back to current path | |
if( base ) { | |
base.set( path.get() ); | |
} | |
var plfEvent = new $.Event( "pageloadfailed" ); | |
// Let listeners know the page load failed. | |
settings.pageContainer.trigger( plfEvent, triggerData ); | |
// If the default behavior is prevented, stop here! | |
// Note that it is the responsibility of the listener/handler | |
// that called preventDefault(), to resolve/reject the | |
// deferred object within the triggerData. | |
if( plfEvent.isDefaultPrevented() ){ | |
return; | |
} | |
// Remove loading message. | |
if ( settings.showLoadMsg ) { | |
// Remove loading message. | |
hideMsg(); | |
//show error message | |
$( "<div class='ui-loader ui-overlay-shadow ui-body-e ui-corner-all'><h1>"+ $.mobile.pageLoadErrorMessage +"</h1></div>" ) | |
.css({ "display": "block", "opacity": 0.96, "top": $window.scrollTop() + 100 }) | |
.appendTo( settings.pageContainer ) | |
.delay( 800 ) | |
.fadeOut( 400, function() { | |
$( this ).remove(); | |
}); | |
} | |
deferred.reject( absUrl, options ); | |
} | |
}); | |
} | |
return deferred.promise(); | |
}; | |
$.mobile.loadPage.defaults = { | |
type: "get", | |
data: undefined, | |
reloadPage: false, | |
role: undefined, // By default we rely on the role defined by the @data-role attribute. | |
showLoadMsg: false, | |
pageContainer: undefined, | |
loadMsgDelay: 50 // This delay allows loads that pull from browser cache to occur without showing the loading message. | |
}; | |
// Show a specific page in the page container. | |
$.mobile.changePage = function( toPage, options ) { | |
// If we are in the midst of a transition, queue the current request. | |
// We'll call changePage() once we're done with the current transition to | |
// service the request. | |
if( isPageTransitioning ) { | |
pageTransitionQueue.unshift( arguments ); | |
return; | |
} | |
var settings = $.extend( {}, $.mobile.changePage.defaults, options ); | |
// Make sure we have a pageContainer to work with. | |
settings.pageContainer = settings.pageContainer || $.mobile.pageContainer; | |
// Make sure we have a fromPage. | |
settings.fromPage = settings.fromPage || $.mobile.activePage; | |
var mpc = settings.pageContainer, | |
pbcEvent = new $.Event( "pagebeforechange" ), | |
triggerData = { toPage: toPage, options: settings }; | |
// Let listeners know we're about to change the current page. | |
mpc.trigger( pbcEvent, triggerData ); | |
// If the default behavior is prevented, stop here! | |
if( pbcEvent.isDefaultPrevented() ){ | |
return; | |
} | |
// We allow "pagebeforechange" observers to modify the toPage in the trigger | |
// data to allow for redirects. Make sure our toPage is updated. | |
toPage = triggerData.toPage; | |
// Set the isPageTransitioning flag to prevent any requests from | |
// entering this method while we are in the midst of loading a page | |
// or transitioning. | |
isPageTransitioning = true; | |
// If the caller passed us a url, call loadPage() | |
// to make sure it is loaded into the DOM. We'll listen | |
// to the promise object it returns so we know when | |
// it is done loading or if an error ocurred. | |
if ( typeof toPage == "string" ) { | |
$.mobile.loadPage( toPage, settings ) | |
.done(function( url, options, newPage, dupCachedPage ) { | |
isPageTransitioning = false; | |
options.duplicateCachedPage = dupCachedPage; | |
$.mobile.changePage( newPage, options ); | |
}) | |
.fail(function( url, options ) { | |
isPageTransitioning = false; | |
//clear out the active button state | |
removeActiveLinkClass( true ); | |
//release transition lock so navigation is free again | |
releasePageTransitionLock(); | |
settings.pageContainer.trigger( "pagechangefailed", triggerData ); | |
}); | |
return; | |
} | |
// The caller passed us a real page DOM element. Update our | |
// internal state and then trigger a transition to the page. | |
var fromPage = settings.fromPage, | |
url = ( settings.dataUrl && path.convertUrlToDataUrl( settings.dataUrl ) ) || toPage.jqmData( "url" ), | |
// The pageUrl var is usually the same as url, except when url is obscured as a dialog url. pageUrl always contains the file path | |
pageUrl = url, | |
fileUrl = path.getFilePath( url ), | |
active = urlHistory.getActive(), | |
activeIsInitialPage = urlHistory.activeIndex === 0, | |
historyDir = 0, | |
pageTitle = document.title, | |
isDialog = settings.role === "dialog" || toPage.jqmData( "role" ) === "dialog"; | |
// By default, we prevent changePage requests when the fromPage and toPage | |
// are the same element, but folks that generate content manually/dynamically | |
// and reuse pages want to be able to transition to the same page. To allow | |
// this, they will need to change the default value of allowSamePageTransition | |
// to true, *OR*, pass it in as an option when they manually call changePage(). | |
// It should be noted that our default transition animations assume that the | |
// formPage and toPage are different elements, so they may behave unexpectedly. | |
// It is up to the developer that turns on the allowSamePageTransitiona option | |
// to either turn off transition animations, or make sure that an appropriate | |
// animation transition is used. | |
if( fromPage && fromPage[0] === toPage[0] && !settings.allowSamePageTransition ) { | |
isPageTransitioning = false; | |
mpc.trigger( "pagechange", triggerData ); | |
return; | |
} | |
// We need to make sure the page we are given has already been enhanced. | |
enhancePage( toPage, settings.role ); | |
// If the changePage request was sent from a hashChange event, check to see if the | |
// page is already within the urlHistory stack. If so, we'll assume the user hit | |
// the forward/back button and will try to match the transition accordingly. | |
if( settings.fromHashChange ) { | |
urlHistory.directHashChange({ | |
currentUrl: url, | |
isBack: function() { historyDir = -1; }, | |
isForward: function() { historyDir = 1; } | |
}); | |
} | |
// Kill the keyboard. | |
// XXX_jblas: We need to stop crawling the entire document to kill focus. Instead, | |
// we should be tracking focus with a live() handler so we already have | |
// the element in hand at this point. | |
// Wrap this in a try/catch block since IE9 throw "Unspecified error" if document.activeElement | |
// is undefined when we are in an IFrame. | |
try { | |
$( document.activeElement || "" ).add( "input:focus, textarea:focus, select:focus" ).blur(); | |
} catch(e) {} | |
// If we're displaying the page as a dialog, we don't want the url | |
// for the dialog content to be used in the hash. Instead, we want | |
// to append the dialogHashKey to the url of the current page. | |
if ( isDialog && active ) { | |
// on the initial page load active.url is undefined and in that case should | |
// be an empty string. Moving the undefined -> empty string back into | |
// urlHistory.addNew seemed imprudent given undefined better represents | |
// the url state | |
url = ( active.url || "" ) + dialogHashKey; | |
} | |
// Set the location hash. | |
if( settings.changeHash !== false && url ) { | |
//disable hash listening temporarily | |
urlHistory.ignoreNextHashChange = true; | |
//update hash and history | |
path.set( url ); | |
} | |
//if title element wasn't found, try the page div data attr too | |
var newPageTitle = toPage.jqmData( "title" ) || toPage.children(":jqmData(role='header')").find(".ui-title" ).text(); | |
if( !!newPageTitle && pageTitle == document.title ) { | |
pageTitle = newPageTitle; | |
} | |
//add page to history stack if it's not back or forward | |
if( !historyDir ) { | |
urlHistory.addNew( url, settings.transition, pageTitle, pageUrl, settings.role ); | |
} | |
//set page title | |
document.title = urlHistory.getActive().title; | |
//set "toPage" as activePage | |
$.mobile.activePage = toPage; | |
// Make sure we have a transition defined. | |
settings.transition = settings.transition | |
|| ( ( historyDir && !activeIsInitialPage ) ? active.transition : undefined ) | |
|| ( isDialog ? $.mobile.defaultDialogTransition : $.mobile.defaultPageTransition ); | |
// If we're navigating back in the URL history, set reverse accordingly. | |
settings.reverse = settings.reverse || historyDir < 0; | |
transitionPages( toPage, fromPage, settings.transition, settings.reverse ) | |
.done(function() { | |
removeActiveLinkClass(); | |
//if there's a duplicateCachedPage, remove it from the DOM now that it's hidden | |
if ( settings.duplicateCachedPage ) { | |
settings.duplicateCachedPage.remove(); | |
} | |
//remove initial build class (only present on first pageshow) | |
$html.removeClass( "ui-mobile-rendering" ); | |
releasePageTransitionLock(); | |
// Let listeners know we're all done changing the current page. | |
mpc.trigger( "pagechange", triggerData ); | |
}); | |
}; | |
$.mobile.changePage.defaults = { | |
transition: undefined, | |
reverse: false, | |
changeHash: true, | |
fromHashChange: false, | |
role: undefined, // By default we rely on the role defined by the @data-role attribute. | |
duplicateCachedPage: undefined, | |
pageContainer: undefined, | |
showLoadMsg: true, //loading message shows by default when pages are being fetched during changePage | |
dataUrl: undefined, | |
fromPage: undefined, | |
allowSamePageTransition: false | |
}; | |
/* Event Bindings - hashchange, submit, and click */ | |
function findClosestLink( ele ) | |
{ | |
while ( ele ) { | |
if ( ele.nodeName.toLowerCase() == "a" ) { | |
break; | |
} | |
ele = ele.parentNode; | |
} | |
return ele; | |
} | |
// The base URL for any given element depends on the page it resides in. | |
function getClosestBaseUrl( ele ) | |
{ | |
// Find the closest page and extract out its url. | |
var url = $( ele ).closest( ".ui-page" ).jqmData( "url" ), | |
base = documentBase.hrefNoHash; | |
if ( !url || !path.isPath( url ) ) { | |
url = base; | |
} | |
return path.makeUrlAbsolute( url, base); | |
} | |
//The following event bindings should be bound after mobileinit has been triggered | |
//the following function is called in the init file | |
$.mobile._registerInternalEvents = function(){ | |
//bind to form submit events, handle with Ajax | |
$( "form" ).live('submit', function( event ) { | |
var $this = $( this ); | |
if( !$.mobile.ajaxEnabled || | |
$this.is( ":jqmData(ajax='false')" ) ) { | |
return; | |
} | |
var type = $this.attr( "method" ), | |
target = $this.attr( "target" ), | |
url = $this.attr( "action" ); | |
// If no action is specified, browsers default to using the | |
// URL of the document containing the form. Since we dynamically | |
// pull in pages from external documents, the form should submit | |
// to the URL for the source document of the page containing | |
// the form. | |
if ( !url ) { | |
// Get the @data-url for the page containing the form. | |
url = getClosestBaseUrl( $this ); | |
if ( url === documentBase.hrefNoHash ) { | |
// The url we got back matches the document base, | |
// which means the page must be an internal/embedded page, | |
// so default to using the actual document url as a browser | |
// would. | |
url = documentUrl.hrefNoSearch; | |
} | |
} | |
url = path.makeUrlAbsolute( url, getClosestBaseUrl($this) ); | |
//external submits use regular HTTP | |
if( path.isExternal( url ) || target ) { | |
return; | |
} | |
$.mobile.changePage( | |
url, | |
{ | |
type: type && type.length && type.toLowerCase() || "get", | |
data: $this.serialize(), | |
transition: $this.jqmData( "transition" ), | |
direction: $this.jqmData( "direction" ), | |
reloadPage: true | |
} | |
); | |
event.preventDefault(); | |
}); | |
//add active state on vclick | |
$( document ).bind( "vclick", function( event ) { | |
// if this isn't a left click we don't care. Its important to note | |
// that when the virtual event is generated it will create | |
if ( event.which > 1 ){ | |
return; | |
} | |
var link = findClosestLink( event.target ); | |
if ( link ) { | |
if ( path.parseUrl( link.getAttribute( "href" ) || "#" ).hash !== "#" ) { | |
removeActiveLinkClass( true ); | |
$activeClickedLink = $( link ).closest( ".ui-btn" ).not( ".ui-disabled" ); | |
$activeClickedLink.addClass( $.mobile.activeBtnClass ); | |
$( "." + $.mobile.activePageClass + " .ui-btn" ).not( link ).blur(); | |
} | |
} | |
}); | |
// click routing - direct to HTTP or Ajax, accordingly | |
$( document ).bind( "click", function( event ) { | |
var link = findClosestLink( event.target ); | |
// If there is no link associated with the click or its not a left | |
// click we want to ignore the click | |
if ( !link || event.which > 1) { | |
return; | |
} | |
var $link = $( link ), | |
//remove active link class if external (then it won't be there if you come back) | |
httpCleanup = function(){ | |
window.setTimeout( function() { removeActiveLinkClass( true ); }, 200 ); | |
}; | |
//if there's a data-rel=back attr, go back in history | |
if( $link.is( ":jqmData(rel='back')" ) ) { | |
window.history.back(); | |
return false; | |
} | |
var baseUrl = getClosestBaseUrl( $link ), | |
//get href, if defined, otherwise default to empty hash | |
href = path.makeUrlAbsolute( $link.attr( "href" ) || "#", baseUrl ); | |
//if ajax is disabled, exit early | |
if( !$.mobile.ajaxEnabled && !path.isEmbeddedPage( href ) ){ | |
httpCleanup(); | |
//use default click handling | |
return; | |
} | |
// XXX_jblas: Ideally links to application pages should be specified as | |
// an url to the application document with a hash that is either | |
// the site relative path or id to the page. But some of the | |
// internal code that dynamically generates sub-pages for nested | |
// lists and select dialogs, just write a hash in the link they | |
// create. This means the actual URL path is based on whatever | |
// the current value of the base tag is at the time this code | |
// is called. For now we are just assuming that any url with a | |
// hash in it is an application page reference. | |
if ( href.search( "#" ) != -1 ) { | |
href = href.replace( /[^#]*#/, "" ); | |
if ( !href ) { | |
//link was an empty hash meant purely | |
//for interaction, so we ignore it. | |
event.preventDefault(); | |
return; | |
} else if ( path.isPath( href ) ) { | |
//we have apath so make it the href we want to load. | |
href = path.makeUrlAbsolute( href, baseUrl ); | |
} else { | |
//we have a simple id so use the documentUrl as its base. | |
href = path.makeUrlAbsolute( "#" + href, documentUrl.hrefNoHash ); | |
} | |
} | |
// Should we handle this link, or let the browser deal with it? | |
var useDefaultUrlHandling = $link.is( "[rel='external']" ) || $link.is( ":jqmData(ajax='false')" ) || $link.is( "[target]" ), | |
// Some embedded browsers, like the web view in Phone Gap, allow cross-domain XHR | |
// requests if the document doing the request was loaded via the file:// protocol. | |
// This is usually to allow the application to "phone home" and fetch app specific | |
// data. We normally let the browser handle external/cross-domain urls, but if the | |
// allowCrossDomainPages option is true, we will allow cross-domain http/https | |
// requests to go through our page loading logic. | |
isCrossDomainPageLoad = ( $.mobile.allowCrossDomainPages && documentUrl.protocol === "file:" && href.search( /^https?:/ ) != -1 ), | |
//check for protocol or rel and its not an embedded page | |
//TODO overlap in logic from isExternal, rel=external check should be | |
// moved into more comprehensive isExternalLink | |
isExternal = useDefaultUrlHandling || ( path.isExternal( href ) && !isCrossDomainPageLoad ); | |
if( isExternal ) { | |
httpCleanup(); | |
//use default click handling | |
return; | |
} | |
//use ajax | |
var transition = $link.jqmData( "transition" ), | |
direction = $link.jqmData( "direction" ), | |
reverse = ( direction && direction === "reverse" ) || | |
// deprecated - remove by 1.0 | |
$link.jqmData( "back" ), | |
//this may need to be more specific as we use data-rel more | |
role = $link.attr( "data-" + $.mobile.ns + "rel" ) || undefined; | |
$.mobile.changePage( href, { transition: transition, reverse: reverse, role: role } ); | |
event.preventDefault(); | |
}); | |
//prefetch pages when anchors with data-prefetch are encountered | |
$( ".ui-page" ).live( "pageshow.prefetch", function(){ | |
var urls = []; | |
$( this ).find( "a:jqmData(prefetch)" ).each(function(){ | |
var url = $( this ).attr( "href" ); | |
if ( url && $.inArray( url, urls ) === -1 ) { | |
urls.push( url ); | |
$.mobile.loadPage( url ); | |
} | |
}); | |
} ); | |
$.mobile._handleHashChange = function( hash ) { | |
//find first page via hash | |
var to = path.stripHash( hash ), | |
//transition is false if it's the first page, undefined otherwise (and may be overridden by default) | |
transition = $.mobile.urlHistory.stack.length === 0 ? "none" : undefined, | |
// default options for the changPage calls made after examining the current state | |
// of the page and the hash | |
changePageOptions = { | |
transition: transition, | |
changeHash: false, | |
fromHashChange: true | |
}; | |
//if listening is disabled (either globally or temporarily), or it's a dialog hash | |
if( !$.mobile.hashListeningEnabled || urlHistory.ignoreNextHashChange ) { | |
urlHistory.ignoreNextHashChange = false; | |
return; | |
} | |
// special case for dialogs | |
if( urlHistory.stack.length > 1 && to.indexOf( dialogHashKey ) > -1 ) { | |
// If current active page is not a dialog skip the dialog and continue | |
// in the same direction | |
if(!$.mobile.activePage.is( ".ui-dialog" )) { | |
//determine if we're heading forward or backward and continue accordingly past | |
//the current dialog | |
urlHistory.directHashChange({ | |
currentUrl: to, | |
isBack: function() { window.history.back(); }, | |
isForward: function() { window.history.forward(); } | |
}); | |
// prevent changePage() | |
return; | |
} else { | |
// if the current active page is a dialog and we're navigating | |
// to a dialog use the dialog objected saved in the stack | |
urlHistory.directHashChange({ | |
currentUrl: to, | |
// regardless of the direction of the history change | |
// do the following | |
either: function( isBack ) { | |
var active = $.mobile.urlHistory.getActive(); | |
to = active.pageUrl; | |
// make sure to set the role, transition and reversal | |
// as most of this is lost by the domCache cleaning | |
$.extend( changePageOptions, { | |
role: active.role, | |
transition: active.transition, | |
reverse: isBack | |
}); | |
} | |
}); | |
} | |
} | |
//if to is defined, load it | |
if ( to ) { | |
// At this point, 'to' can be one of 3 things, a cached page element from | |
// a history stack entry, an id, or site-relative/absolute URL. If 'to' is | |
// an id, we need to resolve it against the documentBase, not the location.href, | |
// since the hashchange could've been the result of a forward/backward navigation | |
// that crosses from an external page/dialog to an internal page/dialog. | |
to = ( typeof to === "string" && !path.isPath( to ) ) ? ( path.makeUrlAbsolute( '#' + to, documentBase ) ) : to; | |
$.mobile.changePage( to, changePageOptions ); | |
} else { | |
//there's no hash, go to the first page in the dom | |
$.mobile.changePage( $.mobile.firstPage, changePageOptions ); | |
} | |
}; | |
//hashchange event handler | |
$window.bind( "hashchange", function( e, triggered ) { | |
$.mobile._handleHashChange( location.hash ); | |
}); | |
//set page min-heights to be device specific | |
$( document ).bind( "pageshow", resetActivePageHeight ); | |
$( window ).bind( "throttledresize", resetActivePageHeight ); | |
};//_registerInternalEvents callback | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : history.pushState support, layered on top of hashchange | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, window ) { | |
// For now, let's Monkeypatch this onto the end of $.mobile._registerInternalEvents | |
// Scope self to pushStateHandler so we can reference it sanely within the | |
// methods handed off as event handlers | |
var pushStateHandler = {}, | |
self = pushStateHandler, | |
$win = $( window ), | |
url = $.mobile.path.parseUrl( location.href ); | |
$.extend( pushStateHandler, { | |
// TODO move to a path helper, this is rather common functionality | |
initialFilePath: (function() { | |
return url.pathname + url.search; | |
})(), | |
initialHref: url.hrefNoHash, | |
// Flag for tracking if a Hashchange naturally occurs after each popstate + replace | |
hashchangeFired: false, | |
state: function() { | |
return { | |
hash: location.hash || "#" + self.initialFilePath, | |
title: document.title, | |
// persist across refresh | |
initialHref: self.initialHref | |
}; | |
}, | |
resetUIKeys: function( url ) { | |
var dialog = $.mobile.dialogHashKey, | |
subkey = "&" + $.mobile.subPageUrlKey, | |
dialogIndex = url.indexOf( dialog ); | |
if( dialogIndex > -1 ) { | |
url = url.slice( 0, dialogIndex ) + "#" + url.slice( dialogIndex ); | |
} else if( url.indexOf( subkey ) > -1 ) { | |
url = url.split( subkey ).join( "#" + subkey ); | |
} | |
return url; | |
}, | |
// TODO sort out a single barrier to hashchange functionality | |
nextHashChangePrevented: function( value ) { | |
$.mobile.urlHistory.ignoreNextHashChange = value; | |
self.onHashChangeDisabled = value; | |
}, | |
// on hash change we want to clean up the url | |
// NOTE this takes place *after* the vanilla navigation hash change | |
// handling has taken place and set the state of the DOM | |
onHashChange: function( e ) { | |
// disable this hash change | |
if( self.onHashChangeDisabled ){ | |
return; | |
} | |
var href, state, | |
hash = location.hash, | |
isPath = $.mobile.path.isPath( hash ); | |
hash = isPath ? hash.replace( "#", "" ) : hash; | |
// propulate the hash when its not available | |
state = self.state(); | |
// make the hash abolute with the current href | |
href = $.mobile.path.makeUrlAbsolute( hash, location.href ); | |
if ( isPath ) { | |
href = self.resetUIKeys( href ); | |
} | |
// replace the current url with the new href and store the state | |
// Note that in some cases we might be replacing an url with the | |
// same url. We do this anyways because we need to make sure that | |
// all of our history entries have a state object associated with | |
// them. This allows us to work around the case where window.history.back() | |
// is called to transition from an external page to an embedded page. | |
// In that particular case, a hashchange event is *NOT* generated by the browser. | |
// Ensuring each history entry has a state object means that onPopState() | |
// will always trigger our hashchange callback even when a hashchange event | |
// is not fired. | |
history.replaceState( state, document.title, href ); | |
}, | |
// on popstate (ie back or forward) we need to replace the hash that was there previously | |
// cleaned up by the additional hash handling | |
onPopState: function( e ) { | |
var poppedState = e.originalEvent.state, holdnexthashchange = false; | |
// if there's no state its not a popstate we care about, ie chrome's initial popstate | |
// or forward popstate | |
if( poppedState ) { | |
// disable any hashchange triggered by the browser | |
self.nextHashChangePrevented( true ); | |
// defer our manual hashchange until after the browser fired | |
// version has come and gone | |
setTimeout(function() { | |
// make sure that the manual hash handling takes place | |
self.nextHashChangePrevented( false ); | |
// change the page based on the hash | |
$.mobile._handleHashChange( poppedState.hash ); | |
}, 100); | |
} | |
}, | |
init: function() { | |
$win.bind( "hashchange", self.onHashChange ); | |
// Handle popstate events the occur through history changes | |
$win.bind( "popstate", self.onPopState ); | |
// if there's no hash, we need to replacestate for returning to home | |
if ( location.hash === "" ) { | |
history.replaceState( self.state(), document.title, location.href ); | |
} | |
} | |
}); | |
$( function() { | |
if( $.mobile.pushStateEnabled && $.support.pushState ){ | |
pushStateHandler.init(); | |
} | |
}); | |
})( jQuery, this );/*! | |
* jQuery Mobile v@VERSION | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
function css3TransitionHandler( name, reverse, $to, $from ) { | |
var deferred = new $.Deferred(), | |
reverseClass = reverse ? " reverse" : "", | |
viewportClass = "ui-mobile-viewport-transitioning viewport-" + name, | |
doneFunc = function() { | |
$to.add( $from ).removeClass( "out in reverse " + name ); | |
if ( $from && $from[ 0 ] !== $to[ 0 ] ) { | |
$from.removeClass( $.mobile.activePageClass ); | |
} | |
$to.parent().removeClass( viewportClass ); | |
deferred.resolve( name, reverse, $to, $from ); | |
}; | |
$to.animationComplete( doneFunc ); | |
$to.parent().addClass( viewportClass ); | |
if ( $from ) { | |
$from.addClass( name + " out" + reverseClass ); | |
} | |
$to.addClass( $.mobile.activePageClass + " " + name + " in" + reverseClass ); | |
return deferred.promise(); | |
} | |
// Make our transition handler public. | |
$.mobile.css3TransitionHandler = css3TransitionHandler; | |
// If the default transition handler is the 'none' handler, replace it with our handler. | |
if ( $.mobile.defaultTransitionHandler === $.mobile.noneTransitionHandler ) { | |
$.mobile.defaultTransitionHandler = css3TransitionHandler; | |
} | |
})( jQuery, this ); | |
/* | |
* jQuery Mobile Framework : "degradeInputs" plugin - degrades inputs to another type after custom enhancements are made. | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.mobile.page.prototype.options.degradeInputs = { | |
color: false, | |
date: false, | |
datetime: false, | |
"datetime-local": false, | |
email: false, | |
month: false, | |
number: false, | |
range: "number", | |
search: "text", | |
tel: false, | |
time: false, | |
url: false, | |
week: false | |
}; | |
$.mobile.page.prototype.options.keepNative = ":jqmData(role='none'), :jqmData(role='nojs')"; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate enhance", function( e ){ | |
var page = $( e.target ).data( "page" ), | |
o = page.options; | |
// degrade inputs to avoid poorly implemented native functionality | |
$( e.target ).find( "input" ).not( o.keepNative ).each(function() { | |
var $this = $( this ), | |
type = this.getAttribute( "type" ), | |
optType = o.degradeInputs[ type ] || "text"; | |
if ( o.degradeInputs[ type ] ) { | |
var html = $( "<div>" ).html( $this.clone() ).html(), | |
// In IE browsers, the type sometimes doesn't exist in the cloned markup, so we replace the closing tag instead | |
hasType = html.indexOf( " type=" ) > -1, | |
findstr = hasType ? /\s+type=["']?\w+['"]?/ : /\/?>/, | |
repstr = " type=\"" + optType + "\" data-" + $.mobile.ns + "type=\"" + type + "\"" + ( hasType ? "" : ">" ); | |
$this.replaceWith( html.replace( findstr, repstr ) ); | |
} | |
}); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "dialog" plugin. | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses. | |
*/ | |
(function( $, window, undefined ) { | |
$.widget( "mobile.dialog", $.mobile.widget, { | |
options: { | |
closeBtnText : "Close", | |
theme : "a", | |
initSelector : ":jqmData(role='dialog')" | |
}, | |
_create: function() { | |
var self = this, | |
$el = this.element, | |
pageTheme = $el.attr( "class" ).match( /ui-body-[a-z]/ ), | |
headerCloseButton = $( "<a href='#' data-" + $.mobile.ns + "icon='delete' data-" + $.mobile.ns + "iconpos='notext'>"+ this.options.closeBtnText + "</a>" ); | |
if( pageTheme.length ){ | |
$el.removeClass( pageTheme[ 0 ] ); | |
} | |
$el.addClass( "ui-body-" + this.options.theme ); | |
// Class the markup for dialog styling | |
// Set aria role | |
$el.attr( "role", "dialog" ) | |
.addClass( "ui-dialog" ) | |
.find( ":jqmData(role='header')" ) | |
.addClass( "ui-corner-top ui-overlay-shadow" ) | |
.prepend( headerCloseButton ) | |
.end() | |
.find( ":jqmData(role='content'),:jqmData(role='footer')" ) | |
.last() | |
.addClass( "ui-corner-bottom ui-overlay-shadow" ); | |
// this must be an anonymous function so that select menu dialogs can replace | |
// the close method. This is a change from previously just defining data-rel=back | |
// on the button and letting nav handle it | |
headerCloseButton.bind( "vclick", function() { | |
self.close(); | |
}); | |
/* bind events | |
- clicks and submits should use the closing transition that the dialog opened with | |
unless a data-transition is specified on the link/form | |
- if the click was on the close button, or the link has a data-rel="back" it'll go back in history naturally | |
*/ | |
$el.bind( "vclick submit", function( event ) { | |
var $target = $( event.target ).closest( event.type === "vclick" ? "a" : "form" ), | |
active; | |
if ( $target.length && !$target.jqmData( "transition" ) ) { | |
active = $.mobile.urlHistory.getActive() || {}; | |
$target.attr( "data-" + $.mobile.ns + "transition", ( active.transition || $.mobile.defaultDialogTransition ) ) | |
.attr( "data-" + $.mobile.ns + "direction", "reverse" ); | |
} | |
}) | |
.bind( "pagehide", function() { | |
$( this ).find( "." + $.mobile.activeBtnClass ).removeClass( $.mobile.activeBtnClass ); | |
}); | |
}, | |
// Close method goes back in history | |
close: function() { | |
window.history.back(); | |
} | |
}); | |
//auto self-init widgets | |
$( $.mobile.dialog.prototype.options.initSelector ).live( "pagecreate", function(){ | |
$( this ).dialog(); | |
}); | |
})( jQuery, this ); | |
/* | |
* jQuery Mobile Framework : This plugin handles theming and layout of headers, footers, and content areas | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.mobile.page.prototype.options.backBtnText = "Back"; | |
$.mobile.page.prototype.options.addBackBtn = false; | |
$.mobile.page.prototype.options.backBtnTheme = null; | |
$.mobile.page.prototype.options.headerTheme = "a"; | |
$.mobile.page.prototype.options.footerTheme = "a"; | |
$.mobile.page.prototype.options.contentTheme = null; | |
$( ":jqmData(role='page'), :jqmData(role='dialog')" ).live( "pagecreate", function( e ) { | |
var $page = $( this ), | |
o = $page.data( "page" ).options, | |
pageTheme = o.theme; | |
$( ":jqmData(role='header'), :jqmData(role='footer'), :jqmData(role='content')", this ).each(function() { | |
var $this = $( this ), | |
role = $this.jqmData( "role" ), | |
theme = $this.jqmData( "theme" ), | |
$headeranchors, | |
leftbtn, | |
rightbtn, | |
backBtn; | |
$this.addClass( "ui-" + role ); | |
//apply theming and markup modifications to page,header,content,footer | |
if ( role === "header" || role === "footer" ) { | |
var thisTheme = theme || ( role === "header" ? o.headerTheme : o.footerTheme ) || pageTheme; | |
//add theme class | |
$this.addClass( "ui-bar-" + thisTheme ); | |
// Add ARIA role | |
$this.attr( "role", role === "header" ? "banner" : "contentinfo" ); | |
// Right,left buttons | |
$headeranchors = $this.children( "a" ); | |
leftbtn = $headeranchors.hasClass( "ui-btn-left" ); | |
rightbtn = $headeranchors.hasClass( "ui-btn-right" ); | |
if ( !leftbtn ) { | |
leftbtn = $headeranchors.eq( 0 ).not( ".ui-btn-right" ).addClass( "ui-btn-left" ).length; | |
} | |
if ( !rightbtn ) { | |
rightbtn = $headeranchors.eq( 1 ).addClass( "ui-btn-right" ).length; | |
} | |
// Auto-add back btn on pages beyond first view | |
if ( o.addBackBtn && role === "header" && | |
$( ".ui-page" ).length > 1 && | |
$this.jqmData( "url" ) !== $.mobile.path.stripHash( location.hash ) && | |
!leftbtn ) { | |
backBtn = $( "<a href='#' class='ui-btn-left' data-"+ $.mobile.ns +"rel='back' data-"+ $.mobile.ns +"icon='arrow-l'>"+ o.backBtnText +"</a>" ).prependTo( $this ); | |
// If theme is provided, override default inheritance | |
backBtn.attr( "data-"+ $.mobile.ns +"theme", o.backBtnTheme || thisTheme ); | |
} | |
// Page title | |
$this.children( "h1, h2, h3, h4, h5, h6" ) | |
.addClass( "ui-title" ) | |
// Regardless of h element number in src, it becomes h1 for the enhanced page | |
.attr({ | |
"tabindex": "0", | |
"role": "heading", | |
"aria-level": "1" | |
}); | |
} else if ( role === "content" ) { | |
if (theme || o.contentTheme) { | |
$this.addClass( "ui-body-" + ( theme || o.contentTheme ) ); | |
} | |
// Add ARIA role | |
$this.attr( "role", "main" ); | |
} | |
}); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "collapsible" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.collapsible", $.mobile.widget, { | |
options: { | |
expandCueText: " click to expand contents", | |
collapseCueText: " click to collapse contents", | |
collapsed: true, | |
heading: ">:header,>legend", | |
theme: null, | |
contentTheme: null, | |
iconTheme: "d", | |
initSelector: ":jqmData(role='collapsible')" | |
}, | |
_create: function() { | |
var $el = this.element, | |
o = this.options, | |
collapsible = $el.addClass( "ui-collapsible" ), | |
collapsibleHeading = $el.find( o.heading ).eq( 0 ), | |
collapsibleContent = collapsible.wrapInner( "<div class='ui-collapsible-content'></div>" ).find( ".ui-collapsible-content" ), | |
collapsibleSet = $el.closest( ":jqmData(role='collapsible-set')" ).addClass( "ui-collapsible-set" ), | |
colllapsiblesInSet = collapsibleSet.children( ":jqmData(role='collapsible')" ); | |
// Replace collapsibleHeading if it's a legend | |
if ( collapsibleHeading.is( "legend" ) ) { | |
collapsibleHeading = $( "<div role='heading'>"+ collapsibleHeading.html() +"</div>" ).insertBefore( collapsibleHeading ); | |
collapsibleHeading.next().remove(); | |
} | |
// If we are in a collapsible set | |
if ( collapsibleSet.length ) { | |
// Inherit the theme from collapsible-set | |
if ( !o.theme ) { | |
o.theme = collapsibleSet.jqmData( "theme" ); | |
} | |
// Inherit the content-theme from collapsible-set | |
if ( !o.contentTheme ) { | |
o.contentTheme = collapsibleSet.jqmData( "content-theme" ); | |
} | |
} | |
collapsibleContent.addClass( ( o.contentTheme ) ? ( "ui-body-" + o.contentTheme ) : ""); | |
collapsibleHeading | |
//drop heading in before content | |
.insertBefore( collapsibleContent ) | |
//modify markup & attributes | |
.addClass( "ui-collapsible-heading" ) | |
.append( "<span class='ui-collapsible-heading-status'></span>" ) | |
.wrapInner( "<a href='#' class='ui-collapsible-heading-toggle'></a>" ) | |
.find( "a:eq(0)" ) | |
.buttonMarkup({ | |
shadow: false, | |
corners: false, | |
iconPos: "left", | |
icon: "plus", | |
theme: o.theme | |
}); | |
if ( !collapsibleSet.length ) { | |
collapsibleHeading | |
.find( "a:eq(0), .ui-btn-inner" ) | |
.addClass( "ui-corner-top ui-corner-bottom" ); | |
} else { | |
// If we are in a collapsible set | |
// Initialize the collapsible set if it's not already initialized | |
if ( !collapsibleSet.jqmData( "collapsiblebound" ) ) { | |
collapsibleSet | |
.jqmData( "collapsiblebound", true ) | |
.bind( "expand", function( event ) { | |
$( event.target ) | |
.closest( ".ui-collapsible" ) | |
.siblings( ".ui-collapsible" ) | |
.trigger( "collapse" ); | |
}); | |
} | |
colllapsiblesInSet.first() | |
.find( "a:eq(0)" ) | |
.addClass( "ui-corner-top" ) | |
.find( ".ui-btn-inner" ) | |
.addClass( "ui-corner-top" ); | |
colllapsiblesInSet.last() | |
.jqmData( "collapsible-last", true ) | |
.find( "a:eq(0)" ) | |
.addClass( "ui-corner-bottom" ) | |
.find( ".ui-btn-inner" ) | |
.addClass( "ui-corner-bottom" ); | |
if ( collapsible.jqmData( "collapsible-last" ) ) { | |
collapsibleHeading | |
.find( "a:eq(0), .ui-btn-inner" ) | |
.addClass( "ui-corner-bottom" ); | |
} | |
} | |
//events | |
collapsible | |
.bind( "expand collapse", function( event ) { | |
if ( !event.isDefaultPrevented() ) { | |
event.preventDefault(); | |
var $this = $( this ), | |
isCollapse = ( event.type === "collapse" ), | |
contentTheme = o.contentTheme; | |
collapsibleHeading | |
.toggleClass( "ui-collapsible-heading-collapsed", isCollapse) | |
.find( ".ui-collapsible-heading-status" ) | |
.text( o.expandCueText ) | |
.end() | |
.find( ".ui-icon" ) | |
.toggleClass( "ui-icon-minus", !isCollapse ) | |
.toggleClass( "ui-icon-plus", isCollapse ); | |
$this.toggleClass( "ui-collapsible-collapsed", isCollapse ); | |
collapsibleContent.toggleClass( "ui-collapsible-content-collapsed", isCollapse ).attr( "aria-hidden", isCollapse ); | |
if ( contentTheme && ( !collapsibleSet.length || collapsible.jqmData( "collapsible-last" ) ) ) { | |
collapsibleHeading | |
.find( "a:eq(0), .ui-btn-inner" ) | |
.toggleClass( "ui-corner-bottom", isCollapse ); | |
collapsibleContent.toggleClass( "ui-corner-bottom", !isCollapse ); | |
} | |
} | |
}) | |
.trigger( o.collapsed ? "collapse" : "expand" ); | |
collapsibleHeading | |
.bind( "click", function( event ) { | |
var type = collapsibleHeading.is( ".ui-collapsible-heading-collapsed" ) ? | |
"expand" : "collapse"; | |
collapsible.trigger( type ); | |
event.preventDefault(); | |
}); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.collapsible.prototype.options.initSelector, e.target ).collapsible(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "fieldcontain" plugin - simple class additions to make form row separators | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.fn.fieldcontain = function( options ) { | |
return this.addClass( "ui-field-contain ui-body ui-br" ); | |
}; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='fieldcontain')", e.target ).fieldcontain(); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : plugin for creating CSS grids | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.fn.grid = function( options ) { | |
return this.each(function() { | |
var $this = $( this ), | |
o = $.extend({ | |
grid: null | |
},options), | |
$kids = $this.children(), | |
gridCols = {solo:1, a:2, b:3, c:4, d:5}, | |
grid = o.grid, | |
iterator; | |
if ( !grid ) { | |
if ( $kids.length <= 5 ) { | |
for ( var letter in gridCols ) { | |
if ( gridCols[ letter ] === $kids.length ) { | |
grid = letter; | |
} | |
} | |
} else { | |
grid = "a"; | |
} | |
} | |
iterator = gridCols[grid]; | |
$this.addClass( "ui-grid-" + grid ); | |
$kids.filter( ":nth-child(" + iterator + "n+1)" ).addClass( "ui-block-a" ); | |
if ( iterator > 1 ) { | |
$kids.filter( ":nth-child(" + iterator + "n+2)" ).addClass( "ui-block-b" ); | |
} | |
if ( iterator > 2 ) { | |
$kids.filter( ":nth-child(3n+3)" ).addClass( "ui-block-c" ); | |
} | |
if ( iterator > 3 ) { | |
$kids.filter( ":nth-child(4n+4)" ).addClass( "ui-block-d" ); | |
} | |
if ( iterator > 4 ) { | |
$kids.filter( ":nth-child(5n+5)" ).addClass( "ui-block-e" ); | |
} | |
}); | |
}; | |
})( jQuery );/* | |
* jQuery Mobile Framework : "navbar" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.navbar", $.mobile.widget, { | |
options: { | |
iconpos: "top", | |
grid: null, | |
initSelector: ":jqmData(role='navbar')" | |
}, | |
_create: function(){ | |
var $navbar = this.element, | |
$navbtns = $navbar.find( "a" ), | |
iconpos = $navbtns.filter( ":jqmData(icon)" ).length ? | |
this.options.iconpos : undefined; | |
$navbar.addClass( "ui-navbar" ) | |
.attr( "role","navigation" ) | |
.find( "ul" ) | |
.grid({ grid: this.options.grid }); | |
if ( !iconpos ) { | |
$navbar.addClass( "ui-navbar-noicons" ); | |
} | |
$navbtns.buttonMarkup({ | |
corners: false, | |
shadow: false, | |
iconpos: iconpos | |
}); | |
$navbar.delegate( "a", "vclick", function( event ) { | |
$navbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass ); | |
$( this ).addClass( $.mobile.activeBtnClass ); | |
}); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.navbar.prototype.options.initSelector, e.target ).navbar(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "listview" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
//Keeps track of the number of lists per page UID | |
//This allows support for multiple nested list in the same page | |
//https://github.com/jquery/jquery-mobile/issues/1617 | |
var listCountPerPage = {}; | |
$.widget( "mobile.listview", $.mobile.widget, { | |
options: { | |
theme: "c", | |
countTheme: "c", | |
headerTheme: "b", | |
dividerTheme: "b", | |
splitIcon: "arrow-r", | |
splitTheme: "b", | |
inset: false, | |
initSelector: ":jqmData(role='listview')" | |
}, | |
_create: function() { | |
var t = this; | |
// create listview markup | |
t.element.addClass(function( i, orig ) { | |
return orig + " ui-listview " + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" ); | |
}); | |
t.refresh( true ); | |
}, | |
_itemApply: function( $list, item ) { | |
var $countli = item.find( ".ui-li-count" ); | |
if ( $countli.length ) { | |
item.addClass( "ui-li-has-count" ); | |
} | |
$countli.addClass( "ui-btn-up-" + ( $list.jqmData( "counttheme" ) || this.options.countTheme ) + " ui-btn-corner-all" ); | |
// TODO class has to be defined in markup | |
item.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ).end() | |
.find( "p, dl" ).addClass( "ui-li-desc" ).end() | |
.find( ">img:eq(0), .ui-link-inherit>img:eq(0)" ).addClass( "ui-li-thumb" ).each(function() { | |
item.addClass( $(this).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" ); | |
}).end() | |
.find( ".ui-li-aside" ).each(function() { | |
var $this = $(this); | |
$this.prependTo( $this.parent() ); //shift aside to front for css float | |
}); | |
}, | |
_removeCorners: function( li, which ) { | |
var top = "ui-corner-top ui-corner-tr ui-corner-tl", | |
bot = "ui-corner-bottom ui-corner-br ui-corner-bl"; | |
li = li.add( li.find( ".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb" ) ); | |
if ( which === "top" ) { | |
li.removeClass( top ); | |
} else if ( which === "bottom" ) { | |
li.removeClass( bot ); | |
} else { | |
li.removeClass( top + " " + bot ); | |
} | |
}, | |
_refreshCorners: function( create ) { | |
var $li, | |
$visibleli, | |
$topli, | |
$bottomli; | |
if ( this.options.inset ) { | |
$li = this.element.children( "li" ); | |
// at create time the li are not visible yet so we need to rely on .ui-screen-hidden | |
$visibleli = create?$li.not( ".ui-screen-hidden" ):$li.filter( ":visible" ); | |
this._removeCorners( $li ); | |
// Select the first visible li element | |
$topli = $visibleli.first() | |
.addClass( "ui-corner-top" ); | |
$topli.add( $topli.find( ".ui-btn-inner" ) ) | |
.find( ".ui-li-link-alt" ) | |
.addClass( "ui-corner-tr" ) | |
.end() | |
.find( ".ui-li-thumb" ) | |
.addClass( "ui-corner-tl" ); | |
// Select the last visible li element | |
$bottomli = $visibleli.last() | |
.addClass( "ui-corner-bottom" ); | |
$bottomli.add( $bottomli.find( ".ui-btn-inner" ) ) | |
.find( ".ui-li-link-alt" ) | |
.addClass( "ui-corner-br" ) | |
.end() | |
.find( ".ui-li-thumb" ) | |
.addClass( "ui-corner-bl" ); | |
} | |
}, | |
refresh: function( create ) { | |
this.parentPage = this.element.closest( ".ui-page" ); | |
this._createSubPages(); | |
var o = this.options, | |
$list = this.element, | |
self = this, | |
dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme, | |
listsplittheme = $list.jqmData( "splittheme" ), | |
listspliticon = $list.jqmData( "spliticon" ), | |
li = $list.children( "li" ), | |
counter = $.support.cssPseudoElement || !$.nodeName( $list[ 0 ], "ol" ) ? 0 : 1, | |
item, itemClass, itemTheme, | |
a, last, splittheme, countParent, icon; | |
if ( counter ) { | |
$list.find( ".ui-li-dec" ).remove(); | |
} | |
for ( var pos = 0, numli = li.length; pos < numli; pos++ ) { | |
item = li.eq( pos ); | |
itemClass = "ui-li"; | |
// If we're creating the element, we update it regardless | |
if ( create || !item.hasClass( "ui-li" ) ) { | |
itemTheme = item.jqmData("theme") || o.theme; | |
a = item.children( "a" ); | |
if ( a.length ) { | |
icon = item.jqmData("icon"); | |
item.buttonMarkup({ | |
wrapperEls: "div", | |
shadow: false, | |
corners: false, | |
iconpos: "right", | |
icon: a.length > 1 || icon === false ? false : icon || "arrow-r", | |
theme: itemTheme | |
}); | |
if ( ( icon != false ) && ( a.length == 1 ) ) { | |
item.addClass( "ui-li-has-arrow" ); | |
} | |
a.first().addClass( "ui-link-inherit" ); | |
if ( a.length > 1 ) { | |
itemClass += " ui-li-has-alt"; | |
last = a.last(); | |
splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme; | |
last.appendTo(item) | |
.attr( "title", last.text() ) | |
.addClass( "ui-li-link-alt" ) | |
.empty() | |
.buttonMarkup({ | |
shadow: false, | |
corners: false, | |
theme: itemTheme, | |
icon: false, | |
iconpos: false | |
}) | |
.find( ".ui-btn-inner" ) | |
.append( | |
$( "<span />" ).buttonMarkup({ | |
shadow: true, | |
corners: true, | |
theme: splittheme, | |
iconpos: "notext", | |
icon: listspliticon || last.jqmData( "icon" ) || o.splitIcon | |
}) | |
); | |
} | |
} else if ( item.jqmData( "role" ) === "list-divider" ) { | |
itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme; | |
item.attr( "role", "heading" ); | |
//reset counter when a divider heading is encountered | |
if ( counter ) { | |
counter = 1; | |
} | |
} else { | |
itemClass += " ui-li-static ui-body-" + itemTheme; | |
} | |
} | |
if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) { | |
countParent = item.is( ".ui-li-static:first" ) ? item : item.find( ".ui-link-inherit" ); | |
countParent.addClass( "ui-li-jsnumbering" ) | |
.prepend( "<span class='ui-li-dec'>" + (counter++) + ". </span>" ); | |
} | |
item.add( item.children( ".ui-btn-inner" ) ).addClass( itemClass ); | |
self._itemApply( $list, item ); | |
} | |
this._refreshCorners( create ); | |
}, | |
//create a string for ID/subpage url creation | |
_idStringEscape: function( str ) { | |
return str.replace(/[^a-zA-Z0-9]/g, '-'); | |
}, | |
_createSubPages: function() { | |
var parentList = this.element, | |
parentPage = parentList.closest( ".ui-page" ), | |
parentUrl = parentPage.jqmData( "url" ), | |
parentId = parentUrl || parentPage[ 0 ][ $.expando ], | |
parentListId = parentList.attr( "id" ), | |
o = this.options, | |
dns = "data-" + $.mobile.ns, | |
self = this, | |
persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ), | |
hasSubPages; | |
if ( typeof listCountPerPage[ parentId ] === "undefined" ) { | |
listCountPerPage[ parentId ] = -1; | |
} | |
parentListId = parentListId || ++listCountPerPage[ parentId ]; | |
$( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function( i ) { | |
var self = this, | |
list = $( this ), | |
listId = list.attr( "id" ) || parentListId + "-" + i, | |
parent = list.parent(), | |
nodeEls = $( list.prevAll().toArray().reverse() ), | |
nodeEls = nodeEls.length ? nodeEls : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" ), | |
title = nodeEls.first().text(),//url limits to first 30 chars of text | |
id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId, | |
theme = list.jqmData( "theme" ) || o.theme, | |
countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme, | |
newPage, anchor; | |
//define hasSubPages for use in later removal | |
hasSubPages = true; | |
newPage = list.detach() | |
.wrap( "<div " + dns + "role='page' " + dns + "url='" + id + "' " + dns + "theme='" + theme + "' " + dns + "count-theme='" + countTheme + "'><div " + dns + "role='content'></div></div>" ) | |
.parent() | |
.before( "<div " + dns + "role='header' " + dns + "theme='" + o.headerTheme + "'><div class='ui-title'>" + title + "</div></div>" ) | |
.after( persistentFooterID ? $( "<div " + dns + "role='footer' " + dns + "id='"+ persistentFooterID +"'>") : "" ) | |
.parent() | |
.appendTo( $.mobile.pageContainer ); | |
newPage.page(); | |
anchor = parent.find('a:first'); | |
if ( !anchor.length ) { | |
anchor = $( "<a/>" ).html( nodeEls || title ).prependTo( parent.empty() ); | |
} | |
anchor.attr( "href", "#" + id ); | |
}).listview(); | |
// on pagehide, remove any nested pages along with the parent page, as long as they aren't active | |
// and aren't embedded | |
if( hasSubPages && | |
parentPage.is( ":jqmData(external-page='true')" ) && | |
parentPage.data("page").options.domCache === false ) { | |
var newRemove = function( e, ui ){ | |
var nextPage = ui.nextPage, npURL; | |
if( ui.nextPage ){ | |
npURL = nextPage.jqmData( "url" ); | |
if( npURL.indexOf( parentUrl + "&" + $.mobile.subPageUrlKey ) !== 0 ){ | |
self.childPages().remove(); | |
parentPage.remove(); | |
} | |
} | |
}; | |
// unbind the original page remove and replace with our specialized version | |
parentPage | |
.unbind( "pagehide.remove" ) | |
.bind( "pagehide.remove", newRemove); | |
} | |
}, | |
// TODO sort out a better way to track sub pages of the listview this is brittle | |
childPages: function(){ | |
var parentUrl = this.parentPage.jqmData( "url" ); | |
return $( ":jqmData(url^='"+ parentUrl + "&" + $.mobile.subPageUrlKey +"')"); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.listview.prototype.options.initSelector, e.target ).listview(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "listview" filter extension | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.mobile.listview.prototype.options.filter = false; | |
$.mobile.listview.prototype.options.filterPlaceholder = "Filter items..."; | |
$.mobile.listview.prototype.options.filterTheme = "c"; | |
$.mobile.listview.prototype.options.filterCallback = function( text, searchValue ){ | |
return text.toLowerCase().indexOf( searchValue ) === -1; | |
}; | |
$( ":jqmData(role='listview')" ).live( "listviewcreate", function() { | |
var list = $( this ), | |
listview = list.data( "listview" ); | |
if ( !listview.options.filter ) { | |
return; | |
} | |
var wrapper = $( "<form>", { | |
"class": "ui-listview-filter ui-bar-" + listview.options.filterTheme, | |
"role": "search" | |
}), | |
search = $( "<input>", { | |
placeholder: listview.options.filterPlaceholder | |
}) | |
.attr( "data-" + $.mobile.ns + "type", "search" ) | |
.jqmData( "lastval", "" ) | |
.bind( "keyup change", function() { | |
var $this = $(this), | |
val = this.value.toLowerCase(), | |
listItems = null, | |
lastval = $this.jqmData( "lastval" ) + "", | |
childItems = false, | |
itemtext = "", | |
item, change; | |
// Change val as lastval for next execution | |
$this.jqmData( "lastval" , val ); | |
change = val.replace( new RegExp( "^" + lastval ) , "" ); | |
if ( val.length < lastval.length || change.length != ( val.length - lastval.length ) ) { | |
// Removed chars or pasted something totaly different, check all items | |
listItems = list.children(); | |
} else { | |
// Only chars added, not removed, only use visible subset | |
listItems = list.children( ":not(.ui-screen-hidden)" ); | |
} | |
if ( val ) { | |
// This handles hiding regular rows without the text we search for | |
// and any list dividers without regular rows shown under it | |
for ( var i = listItems.length - 1; i >= 0; i-- ) { | |
item = $( listItems[ i ] ); | |
itemtext = item.jqmData( "filtertext" ) || item.text(); | |
if ( item.is( "li:jqmData(role=list-divider)" ) ) { | |
item.toggleClass( "ui-filter-hidequeue" , !childItems ); | |
// New bucket! | |
childItems = false; | |
} else if ( listview.options.filterCallback( itemtext, val ) ) { | |
//mark to be hidden | |
item.toggleClass( "ui-filter-hidequeue" , true ); | |
} else { | |
// There"s a shown item in the bucket | |
childItems = true; | |
} | |
} | |
// Show items, not marked to be hidden | |
listItems | |
.filter( ":not(.ui-filter-hidequeue)" ) | |
.toggleClass( "ui-screen-hidden", false ); | |
// Hide items, marked to be hidden | |
listItems | |
.filter( ".ui-filter-hidequeue" ) | |
.toggleClass( "ui-screen-hidden", true ) | |
.toggleClass( "ui-filter-hidequeue", false ); | |
} else { | |
//filtervalue is empty => show all | |
listItems.toggleClass( "ui-screen-hidden", false ); | |
} | |
listview._refreshCorners(); | |
}) | |
.appendTo( wrapper ) | |
.textinput(); | |
if ( $( this ).jqmData( "inset" ) ) { | |
wrapper.addClass( "ui-listview-filter-inset" ); | |
} | |
wrapper.bind( "submit", function() { | |
return false; | |
}) | |
.insertBefore( list ); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "nojs" plugin - class to make elements hidden to A grade browsers | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='nojs')", e.target ).addClass( "ui-nojs" ); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "checkboxradio" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.checkboxradio", $.mobile.widget, { | |
options: { | |
theme: null, | |
initSelector: "input[type='checkbox'],input[type='radio']" | |
}, | |
_create: function() { | |
var self = this, | |
input = this.element, | |
// NOTE: Windows Phone could not find the label through a selector | |
// filter works though. | |
label = input.closest( "form,fieldset,:jqmData(role='page')" ).find( "label" ).filter( "[for='" + input[ 0 ].id + "']"), | |
inputtype = input.attr( "type" ), | |
checkedState = inputtype + "-on", | |
uncheckedState = inputtype + "-off", | |
icon = input.parents( ":jqmData(type='horizontal')" ).length ? undefined : uncheckedState, | |
activeBtn = icon ? "" : " " + $.mobile.activeBtnClass, | |
checkedClass = "ui-" + checkedState + activeBtn, | |
uncheckedClass = "ui-" + uncheckedState, | |
checkedicon = "ui-icon-" + checkedState, | |
uncheckedicon = "ui-icon-" + uncheckedState; | |
if ( inputtype !== "checkbox" && inputtype !== "radio" ) { | |
return; | |
} | |
// Expose for other methods | |
$.extend( this, { | |
label: label, | |
inputtype: inputtype, | |
checkedClass: checkedClass, | |
uncheckedClass: uncheckedClass, | |
checkedicon: checkedicon, | |
uncheckedicon: uncheckedicon | |
}); | |
// If there's no selected theme... | |
if( !this.options.theme ) { | |
this.options.theme = this.element.jqmData( "theme" ); | |
} | |
label.buttonMarkup({ | |
theme: this.options.theme, | |
icon: icon, | |
shadow: false | |
}); | |
// Wrap the input + label in a div | |
input.add( label ) | |
.wrapAll( "<div class='ui-" + inputtype + "'></div>" ); | |
label.bind({ | |
vmouseover: function() { | |
if ( $( this ).parent().is( ".ui-disabled" ) ) { | |
return false; | |
} | |
}, | |
vclick: function( event ) { | |
if ( input.is( ":disabled" ) ) { | |
event.preventDefault(); | |
return; | |
} | |
self._cacheVals(); | |
input.prop( "checked", inputtype === "radio" && true || !input.prop( "checked" ) ); | |
// Input set for common radio buttons will contain all the radio | |
// buttons, but will not for checkboxes. clearing the checked status | |
// of other radios ensures the active button state is applied properly | |
self._getInputSet().not( input ).prop( "checked", false ); | |
self._updateAll(); | |
return false; | |
} | |
}); | |
input | |
.bind({ | |
vmousedown: function() { | |
this._cacheVals(); | |
}, | |
vclick: function() { | |
var $this = $(this); | |
// Adds checked attribute to checked input when keyboard is used | |
if ( $this.is( ":checked" ) ) { | |
$this.prop( "checked", true); | |
self._getInputSet().not($this).prop( "checked", false ); | |
} else { | |
$this.prop( "checked", false ); | |
} | |
self._updateAll(); | |
}, | |
focus: function() { | |
label.addClass( "ui-focus" ); | |
}, | |
blur: function() { | |
label.removeClass( "ui-focus" ); | |
} | |
}); | |
this.refresh(); | |
}, | |
_cacheVals: function() { | |
this._getInputSet().each(function() { | |
var $this = $(this); | |
$this.jqmData( "cacheVal", $this.is( ":checked" ) ); | |
}); | |
}, | |
//returns either a set of radios with the same name attribute, or a single checkbox | |
_getInputSet: function(){ | |
if(this.inputtype == "checkbox") { | |
return this.element; | |
} | |
return this.element.closest( "form,fieldset,:jqmData(role='page')" ) | |
.find( "input[name='"+ this.element.attr( "name" ) +"'][type='"+ this.inputtype +"']" ); | |
}, | |
_updateAll: function() { | |
var self = this; | |
this._getInputSet().each(function() { | |
var $this = $(this); | |
if ( $this.is( ":checked" ) || self.inputtype === "checkbox" ) { | |
$this.trigger( "change" ); | |
} | |
}) | |
.checkboxradio( "refresh" ); | |
}, | |
refresh: function() { | |
var input = this.element, | |
label = this.label, | |
icon = label.find( ".ui-icon" ); | |
// input[0].checked expando doesn't always report the proper value | |
// for checked='checked' | |
if ( $( input[ 0 ] ).prop( "checked" ) ) { | |
label.addClass( this.checkedClass ).removeClass( this.uncheckedClass ); | |
icon.addClass( this.checkedicon ).removeClass( this.uncheckedicon ); | |
} else { | |
label.removeClass( this.checkedClass ).addClass( this.uncheckedClass ); | |
icon.removeClass( this.checkedicon ).addClass( this.uncheckedicon ); | |
} | |
if ( input.is( ":disabled" ) ) { | |
this.disable(); | |
} else { | |
this.enable(); | |
} | |
}, | |
disable: function() { | |
this.element.prop( "disabled", true ).parent().addClass( "ui-disabled" ); | |
}, | |
enable: function() { | |
this.element.prop( "disabled", false ).parent().removeClass( "ui-disabled" ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.checkboxradio.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.checkboxradio(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "button" plugin - links that proxy to native input/buttons | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.button", $.mobile.widget, { | |
options: { | |
theme: null, | |
icon: null, | |
iconpos: null, | |
inline: null, | |
corners: true, | |
shadow: true, | |
iconshadow: true, | |
initSelector: "button, [type='button'], [type='submit'], [type='reset'], [type='image']" | |
}, | |
_create: function() { | |
var $el = this.element, | |
o = this.options, | |
type, | |
name, | |
$buttonPlaceholder; | |
// Add ARIA role | |
this.button = $( "<div></div>" ) | |
.text( $el.text() || $el.val() ) | |
.buttonMarkup({ | |
theme: o.theme, | |
icon: o.icon, | |
iconpos: o.iconpos, | |
inline: o.inline, | |
corners: o.corners, | |
shadow: o.shadow, | |
iconshadow: o.iconshadow | |
}) | |
.insertBefore( $el ) | |
.append( $el.addClass( "ui-btn-hidden" ) ); | |
type = $el.attr( "type" ); | |
name = $el.attr( "name" ); | |
// Add hidden input during submit if input type="submit" has a name. | |
if ( type !== "button" && type !== "reset" && name ) { | |
$el.bind( "vclick", function() { | |
// Add hidden input if it doesn’t already exist. | |
if( $buttonPlaceholder === undefined ) { | |
$buttonPlaceholder = $( "<input>", { | |
type: "hidden", | |
name: $el.attr( "name" ), | |
value: $el.attr( "value" ) | |
}) | |
.insertBefore( $el ); | |
// Bind to doc to remove after submit handling | |
$( document ).submit(function(){ | |
$buttonPlaceholder.remove(); | |
}); | |
} | |
}); | |
} | |
this.refresh(); | |
}, | |
enable: function() { | |
this.element.attr( "disabled", false ); | |
this.button.removeClass( "ui-disabled" ).attr( "aria-disabled", false ); | |
return this._setOption( "disabled", false ); | |
}, | |
disable: function() { | |
this.element.attr( "disabled", true ); | |
this.button.addClass( "ui-disabled" ).attr( "aria-disabled", true ); | |
return this._setOption( "disabled", true ); | |
}, | |
refresh: function() { | |
if ( this.element.attr( "disabled" ) ) { | |
this.disable(); | |
} else { | |
this.enable(); | |
} | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.button.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.button(); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "slider" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, undefined ) { | |
$.widget( "mobile.slider", $.mobile.widget, { | |
options: { | |
theme: null, | |
trackTheme: null, | |
disabled: false, | |
initSelector: "input[type='range'], :jqmData(type='range'), :jqmData(role='slider')" | |
}, | |
_create: function() { | |
// TODO: Each of these should have comments explain what they're for | |
var self = this, | |
control = this.element, | |
parentTheme = control.parents( "[class*='ui-bar-'],[class*='ui-body-']" ).eq( 0 ), | |
parentTheme = parentTheme.length ? parentTheme.attr( "class" ).match( /ui-(bar|body)-([a-z])/ )[ 2 ] : "c", | |
theme = this.options.theme ? this.options.theme : parentTheme, | |
trackTheme = this.options.trackTheme ? this.options.trackTheme : parentTheme, | |
cType = control[ 0 ].nodeName.toLowerCase(), | |
selectClass = ( cType == "select" ) ? "ui-slider-switch" : "", | |
controlID = control.attr( "id" ), | |
labelID = controlID + "-label", | |
label = $( "[for='"+ controlID +"']" ).attr( "id", labelID ), | |
val = function() { | |
return cType == "input" ? parseFloat( control.val() ) : control[0].selectedIndex; | |
}, | |
min = cType == "input" ? parseFloat( control.attr( "min" ) ) : 0, | |
max = cType == "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length-1, | |
step = window.parseFloat( control.attr( "step" ) || 1 ), | |
slider = $( "<div class='ui-slider " + selectClass + " ui-btn-down-" + trackTheme + | |
" ui-btn-corner-all' role='application'></div>" ), | |
handle = $( "<a href='#' class='ui-slider-handle'></a>" ) | |
.appendTo( slider ) | |
.buttonMarkup({ corners: true, theme: theme, shadow: true }) | |
.attr({ | |
"role": "slider", | |
"aria-valuemin": min, | |
"aria-valuemax": max, | |
"aria-valuenow": val(), | |
"aria-valuetext": val(), | |
"title": val(), | |
"aria-labelledby": labelID | |
}), | |
options; | |
$.extend( this, { | |
slider: slider, | |
handle: handle, | |
dragging: false, | |
beforeStart: null, | |
userModified: false | |
}); | |
if ( cType == "select" ) { | |
slider.wrapInner( "<div class='ui-slider-inneroffset'></div>" ); | |
options = control.find( "option" ); | |
control.find( "option" ).each(function( i ) { | |
var side = !i ? "b":"a", | |
corners = !i ? "right" :"left", | |
theme = !i ? " ui-btn-down-" + trackTheme :( " " + $.mobile.activeBtnClass ); | |
$( "<div class='ui-slider-labelbg ui-slider-labelbg-" + side + theme + " ui-btn-corner-" + corners + "'></div>" ) | |
.prependTo( slider ); | |
$( "<span class='ui-slider-label ui-slider-label-" + side + theme + " ui-btn-corner-" + corners + "' role='img'>" + $( this ).text() + "</span>" ) | |
.prependTo( handle ); | |
}); | |
} | |
label.addClass( "ui-slider" ); | |
// monitor the input for updated values | |
control.addClass( cType === "input" ? "ui-slider-input" : "ui-slider-switch" ) | |
.change( function() { | |
self.refresh( val(), true ); | |
}) | |
.keyup( function() { // necessary? | |
self.refresh( val(), true, true ); | |
}) | |
.blur( function() { | |
self.refresh( val(), true ); | |
}); | |
// prevent screen drag when slider activated | |
$( document ).bind( "vmousemove", function( event ) { | |
if ( self.dragging ) { | |
self.refresh( event ); | |
self.userModified = self.userModified || self.beforeStart !== control[0].selectedIndex; | |
return false; | |
} | |
}); | |
slider.bind( "vmousedown", function( event ) { | |
self.dragging = true; | |
self.userModified = false; | |
if ( cType === "select" ) { | |
self.beforeStart = control[0].selectedIndex; | |
} | |
self.refresh( event ); | |
return false; | |
}); | |
slider.add( document ) | |
.bind( "vmouseup", function() { | |
if ( self.dragging ) { | |
self.dragging = false; | |
if ( cType === "select" ) { | |
if ( !self.userModified ) { | |
//tap occurred, but value didn't change. flip it! | |
handle.addClass( "ui-slider-handle-snapping" ); | |
self.refresh( !self.beforeStart ? 1 : 0 ); | |
} | |
} | |
return false; | |
} | |
}); | |
slider.insertAfter( control ); | |
// NOTE force focus on handle | |
this.handle | |
.bind( "vmousedown", function() { | |
$( this ).focus(); | |
}) | |
.bind( "vclick", false ); | |
this.handle | |
.bind( "keydown", function( event ) { | |
var index = val(); | |
if ( self.options.disabled ) { | |
return; | |
} | |
// In all cases prevent the default and mark the handle as active | |
switch ( event.keyCode ) { | |
case $.mobile.keyCode.HOME: | |
case $.mobile.keyCode.END: | |
case $.mobile.keyCode.PAGE_UP: | |
case $.mobile.keyCode.PAGE_DOWN: | |
case $.mobile.keyCode.UP: | |
case $.mobile.keyCode.RIGHT: | |
case $.mobile.keyCode.DOWN: | |
case $.mobile.keyCode.LEFT: | |
event.preventDefault(); | |
if ( !self._keySliding ) { | |
self._keySliding = true; | |
$( this ).addClass( "ui-state-active" ); | |
} | |
break; | |
} | |
// move the slider according to the keypress | |
switch ( event.keyCode ) { | |
case $.mobile.keyCode.HOME: | |
self.refresh( min ); | |
break; | |
case $.mobile.keyCode.END: | |
self.refresh( max ); | |
break; | |
case $.mobile.keyCode.PAGE_UP: | |
case $.mobile.keyCode.UP: | |
case $.mobile.keyCode.RIGHT: | |
self.refresh( index + step ); | |
break; | |
case $.mobile.keyCode.PAGE_DOWN: | |
case $.mobile.keyCode.DOWN: | |
case $.mobile.keyCode.LEFT: | |
self.refresh( index - step ); | |
break; | |
} | |
}) // remove active mark | |
.keyup( function( event ) { | |
if ( self._keySliding ) { | |
self._keySliding = false; | |
$( this ).removeClass( "ui-state-active" ); | |
} | |
}); | |
this.refresh(undefined, undefined, true); | |
}, | |
refresh: function( val, isfromControl, preventInputUpdate ) { | |
if ( this.options.disabled ) { return; } | |
var control = this.element, percent, | |
cType = control[0].nodeName.toLowerCase(), | |
min = cType === "input" ? parseFloat( control.attr( "min" ) ) : 0, | |
max = cType === "input" ? parseFloat( control.attr( "max" ) ) : control.find( "option" ).length - 1; | |
if ( typeof val === "object" ) { | |
var data = val, | |
// a slight tolerance helped get to the ends of the slider | |
tol = 8; | |
if ( !this.dragging || | |
data.pageX < this.slider.offset().left - tol || | |
data.pageX > this.slider.offset().left + this.slider.width() + tol ) { | |
return; | |
} | |
percent = Math.round( ( ( data.pageX - this.slider.offset().left ) / this.slider.width() ) * 100 ); | |
} else { | |
if ( val == null ) { | |
val = cType === "input" ? parseFloat( control.val() ) : control[0].selectedIndex; | |
} | |
percent = ( parseFloat( val ) - min ) / ( max - min ) * 100; | |
} | |
if ( isNaN( percent ) ) { | |
return; | |
} | |
if ( percent < 0 ) { | |
percent = 0; | |
} | |
if ( percent > 100 ) { | |
percent = 100; | |
} | |
var newval = Math.round( ( percent / 100 ) * ( max - min ) ) + min; | |
if ( newval < min ) { | |
newval = min; | |
} | |
if ( newval > max ) { | |
newval = max; | |
} | |
// Flip the stack of the bg colors | |
if ( percent > 60 && cType === "select" ) { | |
// TODO: Dead path? | |
} | |
this.handle.css( "left", percent + "%" ); | |
this.handle.attr( { | |
"aria-valuenow": cType === "input" ? newval : control.find( "option" ).eq( newval ).attr( "value" ), | |
"aria-valuetext": cType === "input" ? newval : control.find( "option" ).eq( newval ).text(), | |
title: newval | |
}); | |
// add/remove classes for flip toggle switch | |
if ( cType === "select" ) { | |
if ( newval === 0 ) { | |
this.slider.addClass( "ui-slider-switch-a" ) | |
.removeClass( "ui-slider-switch-b" ); | |
} else { | |
this.slider.addClass( "ui-slider-switch-b" ) | |
.removeClass( "ui-slider-switch-a" ); | |
} | |
} | |
if ( !preventInputUpdate ) { | |
var valueChanged = false; | |
// update control"s value | |
if ( cType === "input" ) { | |
valueChanged = control.val() !== newval; | |
control.val( newval ); | |
} else { | |
valueChanged = control[ 0 ].selectedIndex !== newval; | |
control[ 0 ].selectedIndex = newval; | |
} | |
if ( !isfromControl && valueChanged ) { | |
control.trigger( "change" ); | |
} | |
} | |
}, | |
enable: function() { | |
this.element.attr( "disabled", false ); | |
this.slider.removeClass( "ui-disabled" ).attr( "aria-disabled", false ); | |
return this._setOption( "disabled", false ); | |
}, | |
disable: function() { | |
this.element.attr( "disabled", true ); | |
this.slider.addClass( "ui-disabled" ).attr( "aria-disabled", true ); | |
return this._setOption( "disabled", true ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.slider.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.slider(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.textinput", $.mobile.widget, { | |
options: { | |
theme: null, | |
initSelector: "input[type='text'], input[type='search'], :jqmData(type='search'), input[type='number'], :jqmData(type='number'), input[type='password'], input[type='email'], input[type='url'], input[type='tel'], textarea, input:not([type])" | |
}, | |
_create: function() { | |
var input = this.element, | |
o = this.options, | |
theme = o.theme, | |
themedParent, themeclass, themeLetter, focusedEl, clearbtn; | |
if ( !theme ) { | |
themedParent = this.element.closest( "[class*='ui-bar-'],[class*='ui-body-']" ); | |
themeLetter = themedParent.length && /ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) ); | |
theme = themeLetter && themeLetter[2] || "c"; | |
} | |
themeclass = " ui-body-" + theme; | |
$( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" ); | |
input.addClass("ui-input-text ui-body-"+ o.theme ); | |
focusedEl = input; | |
// XXX: Temporary workaround for issue 785 (Apple bug 8910589). | |
// Turn off autocorrect and autocomplete on non-iOS 5 devices | |
// since the popup they use can't be dismissed by the user. Note | |
// that we test for the presence of the feature by looking for | |
// the autocorrect property on the input element. We currently | |
// have no test for iOS 5 or newer so we're temporarily using | |
// the touchOverflow support flag for jQM 1.0. Yes, I feel dirty. - jblas | |
if ( typeof input[0].autocorrect !== "undefined" && !$.support.touchOverflow ) { | |
// Set the attribute instead of the property just in case there | |
// is code that attempts to make modifications via HTML. | |
input[0].setAttribute( "autocorrect", "off" ); | |
input[0].setAttribute( "autocomplete", "off" ); | |
} | |
//"search" input widget | |
if ( input.is( "[type='search'],:jqmData(type='search')" ) ) { | |
focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-btn-corner-all ui-btn-shadow ui-icon-searchfield" + themeclass + "'></div>" ).parent(); | |
clearbtn = $( "<a href='#' class='ui-input-clear' title='clear text'>clear text</a>" ) | |
.tap(function( event ) { | |
input.val( "" ).focus(); | |
input.trigger( "change" ); | |
clearbtn.addClass( "ui-input-clear-hidden" ); | |
event.preventDefault(); | |
}) | |
.appendTo( focusedEl ) | |
.buttonMarkup({ | |
icon: "delete", | |
iconpos: "notext", | |
corners: true, | |
shadow: true | |
}); | |
function toggleClear() { | |
if ( !input.val() ) { | |
clearbtn.addClass( "ui-input-clear-hidden" ); | |
} else { | |
clearbtn.removeClass( "ui-input-clear-hidden" ); | |
} | |
} | |
toggleClear(); | |
input.keyup( toggleClear ) | |
.focus( toggleClear ); | |
} else { | |
input.addClass( "ui-corner-all ui-shadow-inset" + themeclass ); | |
} | |
input.focus(function() { | |
focusedEl.addClass( "ui-focus" ); | |
}) | |
.blur(function(){ | |
focusedEl.removeClass( "ui-focus" ); | |
}); | |
// Autogrow | |
if ( input.is( "textarea" ) ) { | |
var extraLineHeight = 15, | |
keyupTimeoutBuffer = 100, | |
keyup = function() { | |
var scrollHeight = input[ 0 ].scrollHeight, | |
clientHeight = input[ 0 ].clientHeight; | |
if ( clientHeight < scrollHeight ) { | |
input.css({ | |
height: (scrollHeight + extraLineHeight) | |
}); | |
} | |
}, | |
keyupTimeout; | |
input.keyup(function() { | |
clearTimeout( keyupTimeout ); | |
keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer ); | |
}); | |
} | |
}, | |
disable: function(){ | |
( this.element.attr( "disabled", true ).is( "[type='search'],:jqmData(type='search')" ) ? | |
this.element.parent() : this.element ).addClass( "ui-disabled" ); | |
}, | |
enable: function(){ | |
( this.element.attr( "disabled", false).is( "[type='search'],:jqmData(type='search')" ) ? | |
this.element.parent() : this.element ).removeClass( "ui-disabled" ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.textinput.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.textinput(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : custom "selectmenu" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
var extendSelect = function( widget ){ | |
var select = widget.select, | |
selectID = widget.selectID, | |
label = widget.label, | |
thisPage = widget.select.closest( ".ui-page" ), | |
screen = $( "<div>", {"class": "ui-selectmenu-screen ui-screen-hidden"} ).appendTo( thisPage ), | |
selectOptions = widget._selectOptions(), | |
isMultiple = widget.isMultiple = widget.select[ 0 ].multiple, | |
buttonId = selectID + "-button", | |
menuId = selectID + "-menu", | |
menuPage = $( "<div data-" + $.mobile.ns + "role='dialog' data-" +$.mobile.ns + "theme='"+ widget.options.menuPageTheme +"'>" + | |
"<div data-" + $.mobile.ns + "role='header'>" + | |
"<div class='ui-title'>" + label.getEncodedText() + "</div>"+ | |
"</div>"+ | |
"<div data-" + $.mobile.ns + "role='content'></div>"+ | |
"</div>" ).appendTo( $.mobile.pageContainer ).page(), | |
listbox = $("<div>", { "class": "ui-selectmenu ui-selectmenu-hidden ui-overlay-shadow ui-corner-all ui-body-" + widget.options.overlayTheme + " " + $.mobile.defaultDialogTransition } ).insertAfter(screen), | |
list = $( "<ul>", { | |
"class": "ui-selectmenu-list", | |
"id": menuId, | |
"role": "listbox", | |
"aria-labelledby": buttonId | |
}).attr( "data-" + $.mobile.ns + "theme", widget.options.theme ).appendTo( listbox ), | |
header = $( "<div>", { | |
"class": "ui-header ui-bar-" + widget.options.theme | |
}).prependTo( listbox ), | |
headerTitle = $( "<h1>", { | |
"class": "ui-title" | |
}).appendTo( header ), | |
headerClose = $( "<a>", { | |
"text": widget.options.closeText, | |
"href": "#", | |
"class": "ui-btn-left" | |
}).attr( "data-" + $.mobile.ns + "iconpos", "notext" ).attr( "data-" + $.mobile.ns + "icon", "delete" ).appendTo( header ).buttonMarkup(), | |
menuPageContent = menuPage.find( ".ui-content" ), | |
menuPageClose = menuPage.find( ".ui-header a" ); | |
$.extend( widget, { | |
select: widget.select, | |
selectID: selectID, | |
buttonId: buttonId, | |
menuId: menuId, | |
thisPage: thisPage, | |
menuPage: menuPage, | |
label: label, | |
screen: screen, | |
selectOptions: selectOptions, | |
isMultiple: isMultiple, | |
theme: widget.options.theme, | |
listbox: listbox, | |
list: list, | |
header: header, | |
headerTitle: headerTitle, | |
headerClose: headerClose, | |
menuPageContent: menuPageContent, | |
menuPageClose: menuPageClose, | |
placeholder: "", | |
build: function() { | |
var self = this; | |
// Create list from select, update state | |
self.refresh(); | |
self.select.attr( "tabindex", "-1" ).focus(function() { | |
$( this ).blur(); | |
self.button.focus(); | |
}); | |
// Button events | |
self.button.bind( "vclick keydown" , function( event ) { | |
if ( event.type == "vclick" || | |
event.keyCode && ( event.keyCode === $.mobile.keyCode.ENTER || | |
event.keyCode === $.mobile.keyCode.SPACE ) ) { | |
self.open(); | |
event.preventDefault(); | |
} | |
}); | |
// Events for list items | |
self.list.attr( "role", "listbox" ) | |
.delegate( ".ui-li>a", "focusin", function() { | |
$( this ).attr( "tabindex", "0" ); | |
}) | |
.delegate( ".ui-li>a", "focusout", function() { | |
$( this ).attr( "tabindex", "-1" ); | |
}) | |
.delegate( "li:not(.ui-disabled, .ui-li-divider)", "click", function( event ) { | |
// index of option tag to be selected | |
var oldIndex = self.select[ 0 ].selectedIndex, | |
newIndex = self.list.find( "li:not(.ui-li-divider)" ).index( this ), | |
option = self._selectOptions().eq( newIndex )[ 0 ]; | |
// toggle selected status on the tag for multi selects | |
option.selected = self.isMultiple ? !option.selected : true; | |
// toggle checkbox class for multiple selects | |
if ( self.isMultiple ) { | |
$( this ).find( ".ui-icon" ) | |
.toggleClass( "ui-icon-checkbox-on", option.selected ) | |
.toggleClass( "ui-icon-checkbox-off", !option.selected ); | |
} | |
// trigger change if value changed | |
if ( self.isMultiple || oldIndex !== newIndex ) { | |
self.select.trigger( "change" ); | |
} | |
//hide custom select for single selects only | |
if ( !self.isMultiple ) { | |
self.close(); | |
} | |
event.preventDefault(); | |
}) | |
.keydown(function( event ) { //keyboard events for menu items | |
var target = $( event.target ), | |
li = target.closest( "li" ), | |
prev, next; | |
// switch logic based on which key was pressed | |
switch ( event.keyCode ) { | |
// up or left arrow keys | |
case 38: | |
prev = li.prev(); | |
// if there's a previous option, focus it | |
if ( prev.length ) { | |
target | |
.blur() | |
.attr( "tabindex", "-1" ); | |
prev.find( "a" ).first().focus(); | |
} | |
return false; | |
break; | |
// down or right arrow keys | |
case 40: | |
next = li.next(); | |
// if there's a next option, focus it | |
if ( next.length ) { | |
target | |
.blur() | |
.attr( "tabindex", "-1" ); | |
next.find( "a" ).first().focus(); | |
} | |
return false; | |
break; | |
// If enter or space is pressed, trigger click | |
case 13: | |
case 32: | |
target.trigger( "click" ); | |
return false; | |
break; | |
} | |
}); | |
// button refocus ensures proper height calculation | |
// by removing the inline style and ensuring page inclusion | |
self.menuPage.bind( "pagehide", function() { | |
self.list.appendTo( self.listbox ); | |
self._focusButton(); | |
// TODO centralize page removal binding / handling in the page plugin. | |
// Suggestion from @jblas to do refcounting | |
// | |
// TODO extremely confusing dependency on the open method where the pagehide.remove | |
// bindings are stripped to prevent the parent page from disappearing. The way | |
// we're keeping pages in the DOM right now sucks | |
// | |
// rebind the page remove that was unbound in the open function | |
// to allow for the parent page removal from actions other than the use | |
// of a dialog sized custom select | |
// | |
// doing this here provides for the back button on the custom select dialog | |
$.mobile._bindPageRemove.call( self.thisPage ); | |
}); | |
// Events on "screen" overlay | |
self.screen.bind( "vclick", function( event ) { | |
self.close(); | |
}); | |
// Close button on small overlays | |
self.headerClose.click( function() { | |
if ( self.menuType == "overlay" ) { | |
self.close(); | |
return false; | |
} | |
}); | |
// track this dependency so that when the parent page | |
// is removed on pagehide it will also remove the menupage | |
self.thisPage.addDependents( this.menuPage ); | |
}, | |
_isRebuildRequired: function() { | |
var list = this.list.find( "li" ), | |
options = this._selectOptions(); | |
// TODO exceedingly naive method to determine difference | |
// ignores value changes etc in favor of a forcedRebuild | |
// from the user in the refresh method | |
return options.text() !== list.text(); | |
}, | |
refresh: function( forceRebuild , foo ){ | |
var self = this, | |
select = this.element, | |
isMultiple = this.isMultiple, | |
options = this._selectOptions(), | |
selected = this.selected(), | |
// return an array of all selected index's | |
indicies = this.selectedIndices(); | |
if ( forceRebuild || this._isRebuildRequired() ) { | |
self._buildList(); | |
} | |
self.setButtonText(); | |
self.setButtonCount(); | |
self.list.find( "li:not(.ui-li-divider)" ) | |
.removeClass( $.mobile.activeBtnClass ) | |
.attr( "aria-selected", false ) | |
.each(function( i ) { | |
if ( $.inArray( i, indicies ) > -1 ) { | |
var item = $( this ); | |
// Aria selected attr | |
item.attr( "aria-selected", true ); | |
// Multiple selects: add the "on" checkbox state to the icon | |
if ( self.isMultiple ) { | |
item.find( ".ui-icon" ).removeClass( "ui-icon-checkbox-off" ).addClass( "ui-icon-checkbox-on" ); | |
} else { | |
item.addClass( $.mobile.activeBtnClass ); | |
} | |
} | |
}); | |
}, | |
close: function() { | |
if ( this.options.disabled || !this.isOpen ) { | |
return; | |
} | |
var self = this; | |
if ( self.menuType == "page" ) { | |
// doesn't solve the possible issue with calling change page | |
// where the objects don't define data urls which prevents dialog key | |
// stripping - changePage has incoming refactor | |
window.history.back(); | |
} else { | |
self.screen.addClass( "ui-screen-hidden" ); | |
self.listbox.addClass( "ui-selectmenu-hidden" ).removeAttr( "style" ).removeClass( "in" ); | |
self.list.appendTo( self.listbox ); | |
self._focusButton(); | |
} | |
// allow the dialog to be closed again | |
self.isOpen = false; | |
}, | |
open: function() { | |
if ( this.options.disabled ) { | |
return; | |
} | |
var self = this, | |
menuHeight = self.list.parent().outerHeight(), | |
menuWidth = self.list.parent().outerWidth(), | |
activePage = $( ".ui-page-active" ), | |
tOverflow = $.support.touchOverflow && $.mobile.touchOverflowEnabled, | |
tScrollElem = activePage.is( ".ui-native-fixed" ) ? activePage.find( ".ui-content" ) : activePage; | |
scrollTop = tOverflow ? tScrollElem.scrollTop() : $( window ).scrollTop(), | |
btnOffset = self.button.offset().top, | |
screenHeight = window.innerHeight, | |
screenWidth = window.innerWidth; | |
//add active class to button | |
self.button.addClass( $.mobile.activeBtnClass ); | |
//remove after delay | |
setTimeout( function() { | |
self.button.removeClass( $.mobile.activeBtnClass ); | |
}, 300); | |
function focusMenuItem() { | |
self.list.find( $.mobile.activeBtnClass ).focus(); | |
} | |
if ( menuHeight > screenHeight - 80 || !$.support.scrollTop ) { | |
// prevent the parent page from being removed from the DOM, | |
// otherwise the results of selecting a list item in the dialog | |
// fall into a black hole | |
self.thisPage.unbind( "pagehide.remove" ); | |
//for webos (set lastscroll using button offset) | |
if ( scrollTop == 0 && btnOffset > screenHeight ) { | |
self.thisPage.one( "pagehide", function() { | |
$( this ).jqmData( "lastScroll", btnOffset ); | |
}); | |
} | |
self.menuPage.one( "pageshow", function() { | |
// silentScroll() is called whenever a page is shown to restore | |
// any previous scroll position the page may have had. We need to | |
// wait for the "silentscroll" event before setting focus to avoid | |
// the browser"s "feature" which offsets rendering to make sure | |
// whatever has focus is in view. | |
$( window ).one( "silentscroll", function() { | |
focusMenuItem(); | |
}); | |
self.isOpen = true; | |
}); | |
self.menuType = "page"; | |
self.menuPageContent.append( self.list ); | |
$.mobile.changePage( self.menuPage, { | |
transition: $.mobile.defaultDialogTransition | |
}); | |
} else { | |
self.menuType = "overlay"; | |
self.screen.height( $(document).height() ) | |
.removeClass( "ui-screen-hidden" ); | |
// Try and center the overlay over the button | |
var roomtop = btnOffset - scrollTop, | |
roombot = scrollTop + screenHeight - btnOffset, | |
halfheight = menuHeight / 2, | |
maxwidth = parseFloat( self.list.parent().css( "max-width" ) ), | |
newtop, newleft; | |
if ( roomtop > menuHeight / 2 && roombot > menuHeight / 2 ) { | |
newtop = btnOffset + ( self.button.outerHeight() / 2 ) - halfheight; | |
} else { | |
// 30px tolerance off the edges | |
newtop = roomtop > roombot ? scrollTop + screenHeight - menuHeight - 30 : scrollTop + 30; | |
} | |
// If the menuwidth is smaller than the screen center is | |
if ( menuWidth < maxwidth ) { | |
newleft = ( screenWidth - menuWidth ) / 2; | |
} else { | |
//otherwise insure a >= 30px offset from the left | |
newleft = self.button.offset().left + self.button.outerWidth() / 2 - menuWidth / 2; | |
// 30px tolerance off the edges | |
if ( newleft < 30 ) { | |
newleft = 30; | |
} else if ( (newleft + menuWidth) > screenWidth ) { | |
newleft = screenWidth - menuWidth - 30; | |
} | |
} | |
self.listbox.append( self.list ) | |
.removeClass( "ui-selectmenu-hidden" ) | |
.css({ | |
top: newtop, | |
left: newleft | |
}) | |
.addClass( "in" ); | |
focusMenuItem(); | |
// duplicate with value set in page show for dialog sized selects | |
self.isOpen = true; | |
} | |
}, | |
_buildList: function() { | |
var self = this, | |
o = this.options, | |
placeholder = this.placeholder, | |
optgroups = [], | |
lis = [], | |
dataIcon = self.isMultiple ? "checkbox-off" : "false"; | |
self.list.empty().filter( ".ui-listview" ).listview( "destroy" ); | |
// Populate menu with options from select element | |
self.select.find( "option" ).each( function( i ) { | |
var $this = $( this ), | |
$parent = $this.parent(), | |
text = $this.getEncodedText(), | |
anchor = "<a href='#'>"+ text +"</a>", | |
classes = [], | |
extraAttrs = []; | |
// Are we inside an optgroup? | |
if ( $parent.is( "optgroup" ) ) { | |
var optLabel = $parent.attr( "label" ); | |
// has this optgroup already been built yet? | |
if ( $.inArray( optLabel, optgroups ) === -1 ) { | |
lis.push( "<li data-" + $.mobile.ns + "role='list-divider'>"+ optLabel +"</li>" ); | |
optgroups.push( optLabel ); | |
} | |
} | |
// Find placeholder text | |
// TODO: Are you sure you want to use getAttribute? ^RW | |
if ( !this.getAttribute( "value" ) || text.length == 0 || $this.jqmData( "placeholder" ) ) { | |
if ( o.hidePlaceholderMenuItems ) { | |
classes.push( "ui-selectmenu-placeholder" ); | |
} | |
placeholder = self.placeholder = text; | |
} | |
// support disabled option tags | |
if ( this.disabled ) { | |
classes.push( "ui-disabled" ); | |
extraAttrs.push( "aria-disabled='true'" ); | |
} | |
lis.push( "<li data-" + $.mobile.ns + "option-index='" + i + "' data-" + $.mobile.ns + "icon='"+ dataIcon +"' class='"+ classes.join(" ") + "' " + extraAttrs.join(" ") +">"+ anchor +"</li>" ); | |
}); | |
self.list.html( lis.join(" ") ); | |
self.list.find( "li" ) | |
.attr({ "role": "option", "tabindex": "-1" }) | |
.first().attr( "tabindex", "0" ); | |
// Hide header close link for single selects | |
if ( !this.isMultiple ) { | |
this.headerClose.hide(); | |
} | |
// Hide header if it's not a multiselect and there's no placeholder | |
if ( !this.isMultiple && !placeholder.length ) { | |
this.header.hide(); | |
} else { | |
this.headerTitle.text( this.placeholder ); | |
} | |
// Now populated, create listview | |
self.list.listview(); | |
}, | |
_button: function(){ | |
return $( "<a>", { | |
"href": "#", | |
"role": "button", | |
// TODO value is undefined at creation | |
"id": this.buttonId, | |
"aria-haspopup": "true", | |
// TODO value is undefined at creation | |
"aria-owns": this.menuId | |
}); | |
} | |
}); | |
}; | |
$( "select" ).live( "selectmenubeforecreate", function(){ | |
var selectmenuWidget = $( this ).data( "selectmenu" ); | |
if( !selectmenuWidget.options.nativeMenu ){ | |
extendSelect( selectmenuWidget ); | |
} | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "selectmenu" plugin | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.widget( "mobile.selectmenu", $.mobile.widget, { | |
options: { | |
theme: null, | |
disabled: false, | |
icon: "arrow-d", | |
iconpos: "right", | |
inline: null, | |
corners: true, | |
shadow: true, | |
iconshadow: true, | |
menuPageTheme: "b", | |
overlayTheme: "a", | |
hidePlaceholderMenuItems: true, | |
closeText: "Close", | |
nativeMenu: true, | |
initSelector: "select:not(:jqmData(role='slider'))" | |
}, | |
_button: function(){ | |
return $( "<div/>" ); | |
}, | |
_theme: function(){ | |
if ( this.options.theme ){ | |
return this.options.theme; | |
} | |
var themedParent, theme; | |
// if no theme is defined, try to find closest theme container | |
// TODO move to core as something like findCurrentTheme | |
themedParent = this.select.closest( "[class*='ui-bar-'], [class*='ui-body-']" ); | |
theme = themedParent.length ? | |
/ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) )[2] : | |
"c"; | |
return theme; | |
}, | |
_setDisabled: function( value ) { | |
this.element.attr( "disabled", value ); | |
this.button.attr( "aria-disabled", value ); | |
return this._setOption( "disabled", value ); | |
}, | |
_focusButton : function() { | |
var self = this; | |
setTimeout( function() { | |
self.button.focus(); | |
}, 40); | |
}, | |
_selectOptions: function() { | |
return this.select.find( "option" ); | |
}, | |
// setup items that are generally necessary for select menu extension | |
_preExtension: function(){ | |
this.select = this.element.wrap( "<div class='ui-select'>" ); | |
this.selectID = this.select.attr( "id" ); | |
this.label = $( "label[for='"+ this.selectID +"']" ).addClass( "ui-select" ); | |
this.isMultiple = this.select[ 0 ].multiple; | |
this.options.theme = this._theme(); | |
}, | |
_create: function() { | |
this._preExtension(); | |
// Allows for extension of the native select for custom selects and other plugins | |
// see select.custom for example extension | |
// TODO explore plugin registration | |
this._trigger( "beforeCreate" ); | |
this.button = this._button(); | |
var self = this, | |
options = this.options, | |
// IE throws an exception at options.item() function when | |
// there is no selected item | |
// select first in this case | |
selectedIndex = this.select[ 0 ].selectedIndex == -1 ? 0 : this.select[ 0 ].selectedIndex, | |
// TODO values buttonId and menuId are undefined here | |
button = this.button | |
.text( $( this.select[ 0 ].options.item( selectedIndex ) ).text() ) | |
.insertBefore( this.select ) | |
.buttonMarkup( { | |
theme: options.theme, | |
icon: options.icon, | |
iconpos: options.iconpos, | |
inline: options.inline, | |
corners: options.corners, | |
shadow: options.shadow, | |
iconshadow: options.iconshadow | |
}); | |
// Opera does not properly support opacity on select elements | |
// In Mini, it hides the element, but not its text | |
// On the desktop,it seems to do the opposite | |
// for these reasons, using the nativeMenu option results in a full native select in Opera | |
if ( options.nativeMenu && window.opera && window.opera.version ) { | |
this.select.addClass( "ui-select-nativeonly" ); | |
} | |
// Add counter for multi selects | |
if ( this.isMultiple ) { | |
this.buttonCount = $( "<span>" ) | |
.addClass( "ui-li-count ui-btn-up-c ui-btn-corner-all" ) | |
.hide() | |
.appendTo( button.addClass('ui-li-has-count') ); | |
} | |
// Disable if specified | |
if ( options.disabled ) { | |
this.disable(); | |
} | |
// Events on native select | |
this.select.change( function() { | |
self.refresh(); | |
}); | |
this.build(); | |
}, | |
build: function() { | |
var self = this; | |
this.select | |
.appendTo( self.button ) | |
.bind( "vmousedown", function() { | |
// Add active class to button | |
self.button.addClass( $.mobile.activeBtnClass ); | |
}) | |
.bind( "focus vmouseover", function() { | |
self.button.trigger( "vmouseover" ); | |
}) | |
.bind( "vmousemove", function() { | |
// Remove active class on scroll/touchmove | |
self.button.removeClass( $.mobile.activeBtnClass ); | |
}) | |
.bind( "change blur vmouseout", function() { | |
self.button.trigger( "vmouseout" ) | |
.removeClass( $.mobile.activeBtnClass ); | |
}) | |
.bind( "change blur", function() { | |
self.button.removeClass( "ui-btn-down-" + self.options.theme ); | |
}); | |
}, | |
selected: function() { | |
return this._selectOptions().filter( ":selected" ); | |
}, | |
selectedIndices: function() { | |
var self = this; | |
return this.selected().map( function() { | |
return self._selectOptions().index( this ); | |
}).get(); | |
}, | |
setButtonText: function() { | |
var self = this, selected = this.selected(); | |
this.button.find( ".ui-btn-text" ).text( function() { | |
if ( !self.isMultiple ) { | |
return selected.text(); | |
} | |
return selected.length ? selected.map( function() { | |
return $( this ).text(); | |
}).get().join( ", " ) : self.placeholder; | |
}); | |
}, | |
setButtonCount: function() { | |
var selected = this.selected(); | |
// multiple count inside button | |
if ( this.isMultiple ) { | |
this.buttonCount[ selected.length > 1 ? "show" : "hide" ]().text( selected.length ); | |
} | |
}, | |
refresh: function() { | |
this.setButtonText(); | |
this.setButtonCount(); | |
}, | |
// open and close preserved in native selects | |
// to simplify users code when looping over selects | |
open: $.noop, | |
close: $.noop, | |
disable: function() { | |
this._setDisabled( true ); | |
this.button.addClass( "ui-disabled" ); | |
}, | |
enable: function() { | |
this._setDisabled( false ); | |
this.button.removeClass( "ui-disabled" ); | |
} | |
}); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( $.mobile.selectmenu.prototype.options.initSelector, e.target ) | |
.not( ":jqmData(role='none'), :jqmData(role='nojs')" ) | |
.selectmenu(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : plugin for making button-like links | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
( function( $, undefined ) { | |
$.fn.buttonMarkup = function( options ) { | |
return this.each( function() { | |
var el = $( this ), | |
o = $.extend( {}, $.fn.buttonMarkup.defaults, { | |
icon: el.jqmData( "icon" ), | |
iconpos: el.jqmData( "iconpos" ), | |
theme: el.jqmData( "theme" ), | |
inline: el.jqmData( "inline" ) | |
}, options ), | |
// Classes Defined | |
innerClass = "ui-btn-inner", | |
buttonClass, iconClass, | |
themedParent, wrap; | |
if ( attachEvents ) { | |
attachEvents(); | |
} | |
// if not, try to find closest theme container | |
if ( !o.theme ) { | |
themedParent = el.closest( "[class*='ui-bar-'],[class*='ui-body-']" ); | |
o.theme = themedParent.length ? | |
/ui-(bar|body)-([a-z])/.exec( themedParent.attr( "class" ) )[2] : | |
"c"; | |
} | |
buttonClass = "ui-btn ui-btn-up-" + o.theme; | |
if ( o.inline ) { | |
buttonClass += " ui-btn-inline"; | |
} | |
if ( o.icon ) { | |
o.icon = "ui-icon-" + o.icon; | |
o.iconpos = o.iconpos || "left"; | |
iconClass = "ui-icon " + o.icon; | |
if ( o.iconshadow ) { | |
iconClass += " ui-icon-shadow"; | |
} | |
} | |
if ( o.iconpos ) { | |
buttonClass += " ui-btn-icon-" + o.iconpos; | |
if ( o.iconpos == "notext" && !el.attr( "title" ) ) { | |
el.attr( "title", el.text() ); | |
} | |
} | |
if ( o.corners ) { | |
buttonClass += " ui-btn-corner-all"; | |
innerClass += " ui-btn-corner-all"; | |
} | |
if ( o.shadow ) { | |
buttonClass += " ui-shadow"; | |
} | |
el.attr( "data-" + $.mobile.ns + "theme", o.theme ) | |
.addClass( buttonClass ); | |
wrap = ( "<D class='" + innerClass + "'><D class='ui-btn-text'></D>" + | |
( o.icon ? "<span class='" + iconClass + "'></span>" : "" ) + | |
"</D>" ).replace( /D/g, o.wrapperEls ); | |
el.wrapInner( wrap ); | |
}); | |
}; | |
$.fn.buttonMarkup.defaults = { | |
corners: true, | |
shadow: true, | |
iconshadow: true, | |
inline: false, | |
wrapperEls: "span" | |
}; | |
function closestEnabledButton( element ) { | |
while ( element ) { | |
var $ele = $( element ); | |
if ( $ele.hasClass( "ui-btn" ) && !$ele.hasClass( "ui-disabled" ) ) { | |
break; | |
} | |
element = element.parentNode; | |
} | |
return element; | |
} | |
var attachEvents = function() { | |
$( document ).bind( { | |
"vmousedown": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-down-" + theme ); | |
} | |
}, | |
"vmousecancel vmouseup": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-down-" + theme ).addClass( "ui-btn-up-" + theme ); | |
} | |
}, | |
"vmouseover focus": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-up-" + theme ).addClass( "ui-btn-hover-" + theme ); | |
} | |
}, | |
"vmouseout blur": function( event ) { | |
var btn = closestEnabledButton( event.target ), | |
$btn, theme; | |
if ( btn ) { | |
$btn = $( btn ); | |
theme = $btn.attr( "data-" + $.mobile.ns + "theme" ); | |
$btn.removeClass( "ui-btn-hover-" + theme ).addClass( "ui-btn-up-" + theme ); | |
} | |
} | |
}); | |
attachEvents = null; | |
}; | |
//links in bars, or those with data-role become buttons | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='button'), .ui-bar > a, .ui-header > a, .ui-footer > a, .ui-bar > :jqmData(role='controlgroup') > a", e.target ) | |
.not( ".ui-btn, :jqmData(role='none'), :jqmData(role='nojs')" ) | |
.buttonMarkup(); | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework: "controlgroup" plugin - corner-rounding for groups of buttons, checks, radios, etc | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$.fn.controlgroup = function( options ) { | |
return this.each(function() { | |
var $el = $( this ), | |
o = $.extend({ | |
direction: $el.jqmData( "type" ) || "vertical", | |
shadow: false, | |
excludeInvisible: true | |
}, options ), | |
groupheading = $el.find( ">legend" ), | |
flCorners = o.direction == "horizontal" ? [ "ui-corner-left", "ui-corner-right" ] : [ "ui-corner-top", "ui-corner-bottom" ], | |
type = $el.find( "input:eq(0)" ).attr( "type" ); | |
// Replace legend with more stylable replacement div | |
if ( groupheading.length ) { | |
$el.wrapInner( "<div class='ui-controlgroup-controls'></div>" ); | |
$( "<div role='heading' class='ui-controlgroup-label'>" + groupheading.html() + "</div>" ).insertBefore( $el.children(0) ); | |
groupheading.remove(); | |
} | |
$el.addClass( "ui-corner-all ui-controlgroup ui-controlgroup-" + o.direction ); | |
// TODO: This should be moved out to the closure | |
// otherwise it is redefined each time controlgroup() is called | |
function flipClasses( els ) { | |
els.removeClass( "ui-btn-corner-all ui-shadow" ) | |
.eq( 0 ).addClass( flCorners[ 0 ] ) | |
.end() | |
.filter( ":last" ).addClass( flCorners[ 1 ] ).addClass( "ui-controlgroup-last" ); | |
} | |
flipClasses( $el.find( ".ui-btn" + ( o.excludeInvisible ? ":visible" : "" ) ) ); | |
flipClasses( $el.find( ".ui-btn-inner" ) ); | |
if ( o.shadow ) { | |
$el.addClass( "ui-shadow" ); | |
} | |
}); | |
}; | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( e ){ | |
$( ":jqmData(role='controlgroup')", e.target ).controlgroup({ excludeInvisible: false }); | |
}); | |
})(jQuery);/* | |
* jQuery Mobile Framework : "links" plugin - simple class additions for links | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
$( document ).bind( "pagecreate create", function( e ){ | |
//links within content areas | |
$( e.target ) | |
.find( "a" ) | |
.not( ".ui-btn, .ui-link-inherit, :jqmData(role='none'), :jqmData(role='nojs')" ) | |
.addClass( "ui-link" ); | |
}); | |
})( jQuery );/* | |
* jQuery Mobile Framework : "fixHeaderFooter" plugin - on-demand positioning for headers,footers | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
var slideDownClass = "ui-header-fixed ui-fixed-inline fade", | |
slideUpClass = "ui-footer-fixed ui-fixed-inline fade", | |
slideDownSelector = ".ui-header:jqmData(position='fixed')", | |
slideUpSelector = ".ui-footer:jqmData(position='fixed')"; | |
$.fn.fixHeaderFooter = function( options ) { | |
if ( !$.support.scrollTop || ( $.support.touchOverflow && $.mobile.touchOverflowEnabled ) ) { | |
return this; | |
} | |
return this.each(function() { | |
var $this = $( this ); | |
if ( $this.jqmData( "fullscreen" ) ) { | |
$this.addClass( "ui-page-fullscreen" ); | |
} | |
// Should be slidedown | |
$this.find( slideDownSelector ).addClass( slideDownClass ); | |
// Should be slideup | |
$this.find( slideUpSelector ).addClass( slideUpClass ); | |
}); | |
}; | |
// single controller for all showing,hiding,toggling | |
$.mobile.fixedToolbars = (function() { | |
if ( !$.support.scrollTop || ( $.support.touchOverflow && $.mobile.touchOverflowEnabled ) ) { | |
return; | |
} | |
var stickyFooter, delayTimer, | |
currentstate = "inline", | |
autoHideMode = false, | |
showDelay = 100, | |
ignoreTargets = "a,input,textarea,select,button,label,.ui-header-fixed,.ui-footer-fixed", | |
toolbarSelector = ".ui-header-fixed:first, .ui-footer-fixed:not(.ui-footer-duplicate):last", | |
// for storing quick references to duplicate footers | |
supportTouch = $.support.touch, | |
touchStartEvent = supportTouch ? "touchstart" : "mousedown", | |
touchStopEvent = supportTouch ? "touchend" : "mouseup", | |
stateBefore = null, | |
scrollTriggered = false, | |
touchToggleEnabled = true; | |
function showEventCallback( event ) { | |
// An event that affects the dimensions of the visual viewport has | |
// been triggered. If the header and/or footer for the current page are in overlay | |
// mode, we want to hide them, and then fire off a timer to show them at a later | |
// point. Events like a resize can be triggered continuously during a scroll, on | |
// some platforms, so the timer is used to delay the actual positioning until the | |
// flood of events have subsided. | |
// | |
// If we are in autoHideMode, we don't do anything because we know the scroll | |
// callbacks for the plugin will fire off a show when the scrolling has stopped. | |
if ( !autoHideMode && currentstate === "overlay" ) { | |
if ( !delayTimer ) { | |
$.mobile.fixedToolbars.hide( true ); | |
} | |
$.mobile.fixedToolbars.startShowTimer(); | |
} | |
} | |
$(function() { | |
var $document = $( document ), | |
$window = $( window ); | |
$document | |
.bind( "vmousedown", function( event ) { | |
if ( touchToggleEnabled ) { | |
stateBefore = currentstate; | |
} | |
}) | |
.bind( "vclick", function( event ) { | |
if ( touchToggleEnabled ) { | |
if ( $(event.target).closest( ignoreTargets ).length ) { | |
return; | |
} | |
if ( !scrollTriggered ) { | |
$.mobile.fixedToolbars.toggle( stateBefore ); | |
stateBefore = null; | |
} | |
} | |
}) | |
.bind( "silentscroll", showEventCallback ); | |
// The below checks first for a $(document).scrollTop() value, and if zero, binds scroll events to $(window) instead. | |
// If the scrollTop value is actually zero, both will return zero anyway. | |
// | |
// Works with $(document), not $(window) : Opera Mobile (WinMO phone; kinda broken anyway) | |
// Works with $(window), not $(document) : IE 7/8 | |
// Works with either $(window) or $(document) : Chrome, FF 3.6/4, Android 1.6/2.1, iOS | |
// Needs work either way : BB5, Opera Mobile (iOS) | |
( ( $document.scrollTop() === 0 ) ? $window : $document ) | |
.bind( "scrollstart", function( event ) { | |
scrollTriggered = true; | |
if ( stateBefore === null ) { | |
stateBefore = currentstate; | |
} | |
// We only enter autoHideMode if the headers/footers are in | |
// an overlay state or the show timer was started. If the | |
// show timer is set, clear it so the headers/footers don't | |
// show up until after we're done scrolling. | |
var isOverlayState = stateBefore == "overlay"; | |
autoHideMode = isOverlayState || !!delayTimer; | |
if ( autoHideMode ) { | |
$.mobile.fixedToolbars.clearShowTimer(); | |
if ( isOverlayState ) { | |
$.mobile.fixedToolbars.hide( true ); | |
} | |
} | |
}) | |
.bind( "scrollstop", function( event ) { | |
if ( $( event.target ).closest( ignoreTargets ).length ) { | |
return; | |
} | |
scrollTriggered = false; | |
if ( autoHideMode ) { | |
$.mobile.fixedToolbars.startShowTimer(); | |
autoHideMode = false; | |
} | |
stateBefore = null; | |
}); | |
$window.bind( "resize", showEventCallback ); | |
}); | |
// 1. Before page is shown, check for duplicate footer | |
// 2. After page is shown, append footer to new page | |
$( ".ui-page" ) | |
.live( "pagebeforeshow", function( event, ui ) { | |
var page = $( event.target ), | |
footer = page.find( ":jqmData(role='footer')" ), | |
id = footer.data( "id" ), | |
prevPage = ui.prevPage, | |
prevFooter = prevPage && prevPage.find( ":jqmData(role='footer')" ), | |
prevFooterMatches = prevFooter.length && prevFooter.jqmData( "id" ) === id; | |
if ( id && prevFooterMatches ) { | |
stickyFooter = footer; | |
setTop( stickyFooter.removeClass( "fade in out" ).appendTo( $.mobile.pageContainer ) ); | |
} | |
}) | |
.live( "pageshow", function( event, ui ) { | |
var $this = $( this ); | |
if ( stickyFooter && stickyFooter.length ) { | |
setTimeout(function() { | |
setTop( stickyFooter.appendTo( $this ).addClass( "fade" ) ); | |
stickyFooter = null; | |
}, 500); | |
} | |
$.mobile.fixedToolbars.show( true, this ); | |
}); | |
// When a collapsiable is hidden or shown we need to trigger the fixed toolbar to reposition itself (#1635) | |
$( ".ui-collapsible-contain" ).live( "collapse expand", showEventCallback ); | |
// element.getBoundingClientRect() is broken in iOS 3.2.1 on the iPad. The | |
// coordinates inside of the rect it returns don't have the page scroll position | |
// factored out of it like the other platforms do. To get around this, | |
// we'll just calculate the top offset the old fashioned way until core has | |
// a chance to figure out how to handle this situation. | |
// | |
// TODO: We'll need to get rid of getOffsetTop() once a fix gets folded into core. | |
function getOffsetTop( ele ) { | |
var top = 0, | |
op, body; | |
if ( ele ) { | |
body = document.body; | |
op = ele.offsetParent; | |
top = ele.offsetTop; | |
while ( ele && ele != body ) { | |
top += ele.scrollTop || 0; | |
if ( ele == op ) { | |
top += op.offsetTop; | |
op = ele.offsetParent; | |
} | |
ele = ele.parentNode; | |
} | |
} | |
return top; | |
} | |
function setTop( el ) { | |
var fromTop = $(window).scrollTop(), | |
thisTop = getOffsetTop( el[ 0 ] ), // el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. | |
thisCSStop = el.css( "top" ) == "auto" ? 0 : parseFloat(el.css( "top" )), | |
screenHeight = window.innerHeight, | |
thisHeight = el.outerHeight(), | |
useRelative = el.parents( ".ui-page:not(.ui-page-fullscreen)" ).length, | |
relval; | |
if ( el.is( ".ui-header-fixed" ) ) { | |
relval = fromTop - thisTop + thisCSStop; | |
if ( relval < thisTop ) { | |
relval = 0; | |
} | |
return el.css( "top", useRelative ? relval : fromTop ); | |
} else { | |
// relval = -1 * (thisTop - (fromTop + screenHeight) + thisCSStop + thisHeight); | |
// if ( relval > thisTop ) { relval = 0; } | |
relval = fromTop + screenHeight - thisHeight - (thisTop - thisCSStop ); | |
return el.css( "top", useRelative ? relval : fromTop + screenHeight - thisHeight ); | |
} | |
} | |
// Exposed methods | |
return { | |
show: function( immediately, page ) { | |
$.mobile.fixedToolbars.clearShowTimer(); | |
currentstate = "overlay"; | |
var $ap = page ? $( page ) : | |
( $.mobile.activePage ? $.mobile.activePage : | |
$( ".ui-page-active" ) ); | |
return $ap.children( toolbarSelector ).each(function() { | |
var el = $( this ), | |
fromTop = $( window ).scrollTop(), | |
// el.offset().top returns the wrong value on iPad iOS 3.2.1, call our workaround instead. | |
thisTop = getOffsetTop( el[ 0 ] ), | |
screenHeight = window.innerHeight, | |
thisHeight = el.outerHeight(), | |
alreadyVisible = ( el.is( ".ui-header-fixed" ) && fromTop <= thisTop + thisHeight ) || | |
( el.is( ".ui-footer-fixed" ) && thisTop <= fromTop + screenHeight ); | |
// Add state class | |
el.addClass( "ui-fixed-overlay" ).removeClass( "ui-fixed-inline" ); | |
if ( !alreadyVisible && !immediately ) { | |
el.animationComplete(function() { | |
el.removeClass( "in" ); | |
}).addClass( "in" ); | |
} | |
setTop(el); | |
}); | |
}, | |
hide: function( immediately ) { | |
currentstate = "inline"; | |
var $ap = $.mobile.activePage ? $.mobile.activePage : | |
$( ".ui-page-active" ); | |
return $ap.children( toolbarSelector ).each(function() { | |
var el = $(this), | |
thisCSStop = el.css( "top" ), | |
classes; | |
thisCSStop = thisCSStop == "auto" ? 0 : | |
parseFloat(thisCSStop); | |
// Add state class | |
el.addClass( "ui-fixed-inline" ).removeClass( "ui-fixed-overlay" ); | |
if ( thisCSStop < 0 || ( el.is( ".ui-header-fixed" ) && thisCSStop !== 0 ) ) { | |
if ( immediately ) { | |
el.css( "top", 0); | |
} else { | |
if ( el.css( "top" ) !== "auto" && parseFloat( el.css( "top" ) ) !== 0 ) { | |
classes = "out reverse"; | |
el.animationComplete(function() { | |
el.removeClass( classes ).css( "top", 0 ); | |
}).addClass( classes ); | |
} | |
} | |
} | |
}); | |
}, | |
startShowTimer: function() { | |
$.mobile.fixedToolbars.clearShowTimer(); | |
var args = [].slice.call( arguments ); | |
delayTimer = setTimeout(function() { | |
delayTimer = undefined; | |
$.mobile.fixedToolbars.show.apply( null, args ); | |
}, showDelay); | |
}, | |
clearShowTimer: function() { | |
if ( delayTimer ) { | |
clearTimeout( delayTimer ); | |
} | |
delayTimer = undefined; | |
}, | |
toggle: function( from ) { | |
if ( from ) { | |
currentstate = from; | |
} | |
return ( currentstate === "overlay" ) ? $.mobile.fixedToolbars.hide() : | |
$.mobile.fixedToolbars.show(); | |
}, | |
setTouchToggleEnabled: function( enabled ) { | |
touchToggleEnabled = enabled; | |
} | |
}; | |
})(); | |
//auto self-init widgets | |
$( document ).bind( "pagecreate create", function( event ) { | |
if ( $( ":jqmData(position='fixed')", event.target ).length ) { | |
$( event.target ).each(function() { | |
if ( !$.support.scrollTop || ( $.support.touchOverflow && $.mobile.touchOverflowEnabled ) ) { | |
return this; | |
} | |
var $this = $( this ); | |
if ( $this.jqmData( "fullscreen" ) ) { | |
$this.addClass( "ui-page-fullscreen" ); | |
} | |
// Should be slidedown | |
$this.find( slideDownSelector ).addClass( slideDownClass ); | |
// Should be slideup | |
$this.find( slideUpSelector ).addClass( slideUpClass ); | |
}) | |
} | |
}); | |
})( jQuery ); | |
/* | |
* jQuery Mobile Framework : "fixHeaderFooter" native plugin - Behavior for "fixed" headers,footers, and scrolling inner content | |
* Copyright (c) jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, undefined ) { | |
// Enable touch overflow scrolling when it's natively supported | |
$.mobile.touchOverflowEnabled = false; | |
// Enabled zoom when touch overflow is enabled. Can cause usability issues, unfortunately | |
$.mobile.touchOverflowZoomEnabled = false; | |
$( document ).bind( "pagecreate", function( event ) { | |
if( $.support.touchOverflow && $.mobile.touchOverflowEnabled ){ | |
var $target = $( event.target ), | |
scrollStartY = 0; | |
if( $target.is( ":jqmData(role='page')" ) ){ | |
$target.each(function() { | |
var $page = $( this ), | |
$fixies = $page.find( ":jqmData(role='header'), :jqmData(role='footer')" ).filter( ":jqmData(position='fixed')" ), | |
fullScreen = $page.jqmData( "fullscreen" ), | |
$scrollElem = $fixies.length ? $page.find( ".ui-content" ) : $page; | |
$page.addClass( "ui-mobile-touch-overflow" ); | |
$scrollElem.bind( "scrollstop", function(){ | |
if( $scrollElem.scrollTop() > 0 ){ | |
window.scrollTo( 0, $.mobile.defaultHomeScroll ); | |
} | |
}); | |
if( $fixies.length ){ | |
$page.addClass( "ui-native-fixed" ); | |
if( fullScreen ){ | |
$page.addClass( "ui-native-fullscreen" ); | |
$fixies.addClass( "fade in" ); | |
$( document ).bind( "vclick", function(){ | |
$fixies | |
.removeClass( "ui-native-bars-hidden" ) | |
.toggleClass( "in out" ) | |
.animationComplete(function(){ | |
$(this).not( ".in" ).addClass( "ui-native-bars-hidden" ); | |
}); | |
}); | |
} | |
} | |
}); | |
} | |
} | |
}); | |
})( jQuery ); | |
/*! | |
* jQuery Mobile v@VERSION | |
* http://jquerymobile.com/ | |
* | |
* Copyright 2010, jQuery Project | |
* Dual licensed under the MIT or GPL Version 2 licenses. | |
* http://jquery.org/license | |
*/ | |
(function( $, window, undefined ) { | |
var $html = $( "html" ), | |
$head = $( "head" ), | |
$window = $( window ); | |
// trigger mobileinit event - useful hook for configuring $.mobile settings before they're used | |
$( window.document ).trigger( "mobileinit" ); | |
// support conditions | |
// if device support condition(s) aren't met, leave things as they are -> a basic, usable experience, | |
// otherwise, proceed with the enhancements | |
if ( !$.mobile.gradeA() ) { | |
return; | |
} | |
// override ajaxEnabled on platforms that have known conflicts with hash history updates | |
// or generally work better browsing in regular http for full page refreshes (BB5, Opera Mini) | |
if ( $.mobile.ajaxBlacklist ) { | |
$.mobile.ajaxEnabled = false; | |
} | |
// add mobile, initial load "rendering" classes to docEl | |
$html.addClass( "ui-mobile ui-mobile-rendering" ); | |
// loading div which appears during Ajax requests | |
// will not appear if $.mobile.loadingMessage is false | |
var $loader = $( "<div class='ui-loader ui-body-a ui-corner-all'><span class='ui-icon ui-icon-loading spin'></span><h1></h1></div>" ); | |
$.extend($.mobile, { | |
// turn on/off page loading message. | |
showPageLoadingMsg: function() { | |
if ( $.mobile.loadingMessage ) { | |
var activeBtn = $( "." + $.mobile.activeBtnClass ).first(); | |
$loader | |
.find( "h1" ) | |
.text( $.mobile.loadingMessage ) | |
.end() | |
.appendTo( $.mobile.pageContainer ) | |
// position at y center (if scrollTop supported), above the activeBtn (if defined), or just 100px from top | |
.css({ | |
top: $.support.scrollTop && $window.scrollTop() + $window.height() / 2 || | |
activeBtn.length && activeBtn.offset().top || 100 | |
}); | |
} | |
$html.addClass( "ui-loading" ); | |
}, | |
hidePageLoadingMsg: function() { | |
$html.removeClass( "ui-loading" ); | |
}, | |
// find and enhance the pages in the dom and transition to the first page. | |
initializePage: function() { | |
// find present pages | |
var $pages = $( ":jqmData(role='page')" ); | |
// if no pages are found, create one with body's inner html | |
if ( !$pages.length ) { | |
$pages = $( "body" ).wrapInner( "<div data-" + $.mobile.ns + "role='page'></div>" ).children( 0 ); | |
} | |
// add dialogs, set data-url attrs | |
$pages.add( ":jqmData(role='dialog')" ).each(function() { | |
var $this = $(this); | |
// unless the data url is already set set it to the pathname | |
if ( !$this.jqmData("url") ) { | |
$this.attr( "data-" + $.mobile.ns + "url", $this.attr( "id" ) || location.pathname + location.search ); | |
} | |
}); | |
// define first page in dom case one backs out to the directory root (not always the first page visited, but defined as fallback) | |
$.mobile.firstPage = $pages.first(); | |
// define page container | |
$.mobile.pageContainer = $pages.first().parent().addClass( "ui-mobile-viewport" ); | |
// alert listeners that the pagecontainer has been determined for binding | |
// to events triggered on it | |
$window.trigger( "pagecontainercreate" ); | |
// cue page loading message | |
$.mobile.showPageLoadingMsg(); | |
// if hashchange listening is disabled or there's no hash deeplink, change to the first page in the DOM | |
if ( !$.mobile.hashListeningEnabled || !$.mobile.path.stripHash( location.hash ) ) { | |
$.mobile.changePage( $.mobile.firstPage, { transition: "none", reverse: true, changeHash: false, fromHashChange: true } ); | |
} | |
// otherwise, trigger a hashchange to load a deeplink | |
else { | |
$window.trigger( "hashchange", [ true ] ); | |
} | |
} | |
}); | |
// This function injects a meta viewport tag to prevent scaling. Off by default, on by default when touchOverflow scrolling is enabled | |
function disableZoom() { | |
var cont = "user-scalable=no", | |
meta = $( "meta[name='viewport']" ); | |
if( meta.length ){ | |
meta.attr( "content", meta.attr( "content" ) + ", " + cont ); | |
} | |
else{ | |
$( "head" ).prepend( "<meta>", { "name": "viewport", "content": cont } ); | |
} | |
} | |
// if touch-overflow is enabled, disable user scaling, as it creates usability issues | |
if( $.support.touchOverflow && $.mobile.touchOverflowEnabled && !$.mobile.touchOverflowZoomEnabled ){ | |
disableZoom(); | |
} | |
// initialize events now, after mobileinit has occurred | |
$.mobile._registerInternalEvents(); | |
// check which scrollTop value should be used by scrolling to 1 immediately at domready | |
// then check what the scroll top is. Android will report 0... others 1 | |
// note that this initial scroll won't hide the address bar. It's just for the check. | |
$(function() { | |
window.scrollTo( 0, 1 ); | |
// if defaultHomeScroll hasn't been set yet, see if scrollTop is 1 | |
// it should be 1 in most browsers, but android treats 1 as 0 (for hiding addr bar) | |
// so if it's 1, use 0 from now on | |
$.mobile.defaultHomeScroll = ( !$.support.scrollTop || $(window).scrollTop() === 1 ) ? 0 : 1; | |
//dom-ready inits | |
if( $.mobile.autoInitializePage ){ | |
$.mobile.initializePage(); | |
} | |
// window load event | |
// hide iOS browser chrome on load | |
$window.load( $.mobile.silentScroll ); | |
}); | |
})( jQuery, this ); | |
<?php | <?php |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
include_header("Busness R&D", "index"); | include_header("Busness R&D", "index"); |
if ($_SESSION['authed'] == true) { | |
echo '<ul data-role="listview" data-theme="e" data-groupingtheme="e"> | |
<li data-role="list-divider" > Admin Features </li> | |
<li><a href="myway_timeliness_calculate.php"><h3>myway_timeliness_calculate</h3> | |
<p>myway_timeliness_calculate</p></a></li> | |
<li><a href="myway_timeliness_reconcile.php"><h3>myway_timeliness_reconcile</h3> | |
<p>myway_timeliness_reconcile</p></a></li> | |
<li><a href="servicealert_editor.php"><h3>servicealert_editor</h3> | |
<p>servicealert_editor</p></a></li> | |
</ul>'; | |
} | |
?> | ?> |
<ul data-role="listview" data-theme="e" data-groupingtheme="e"> | <ul data-role="listview" data-theme="e" data-groupingtheme="e"> |
<li data-role="list-divider" > Experimental Features </li> | <li data-role="list-divider" > Experimental Features </li> |
<li><a href="mywaybalance.php"><h3>MyWay Balance for mobile</h3> | |
<p>Mobile viewer for MyWay balance. Warning! No HTTPS security.</p></a></li> | |
<li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3> | <li><a href="busstopdensity.php"><h3>Bus Stop Density Map</h3> |
<p>Analysis of bus stop coverage</p></a></li> | <p>Analysis of bus stop coverage</p></a></li> |
<li><a href="stopBrowser.php"><h3>Bus Stop Browser Map</h3> | <li><a href="stopBrowser.php"><h3>Bus Stop Browser Map</h3> |
<p>Bus stop location/route browser</p></a></li> | <p>Bus stop location/route browser</p></a></li> |
</ul> | </ul> |
<ul data-role="listview" data-theme="e" data-groupingtheme="e"> | </div> |
<li data-role="list-divider" > MyWay Timeliness Graphs </li> | |
<li><a href="myway_timeliness.php"><h3>Timeliness over Day</h3> | |
<p>Displays the deviation from the timetable over the day</p></a></li> | |
<li><a href="myway_timeliness_freqdist.php"><h3>Frequency Distribution of Time Deviation</h3> | |
<p>Displays spread of time deviations</p></a></li> | |
<li><a href="myway_timeliness_route.php"><h3>Timeliness over Route</h3> | |
<p>Displays the deviation from timetable as a specific route progresses</p></a></li> | |
<li><a href="myway_timeliness_stop.php"><h3>Timeliness at Stop</h3> | |
<p>Displays the deviation from the timetable at a specific stop</p></a></li> | |
</ul> | |
</div> | |
<?php | <?php |
include_footer() | include_footer() |
?> | ?> |
<?php | |
function cleanString($subject) | |
{ | |
$subject = str_replace(" ", " ", $subject); | |
$subject = str_replace("&", "&", $subject); | |
$subject = preg_replace('/[^\r\n\t\x20-\x7E\xA0-\xFF]/', '', $subject); | |
$subject = str_replace(" ", " ", $subject); | |
return trim($subject); | |
} | |
$return = Array(); | |
/*if (file_exists("mywayresponse.txt")) { | |
@$fh = fopen("mywayresponse.txt", 'r'); | |
if ($fh) { | |
$pageHTML = fread($fh, filesize("mywayresponse.txt")); | |
fclose($fh); | |
} | |
}*/ | |
//set POST variables | |
$url = 'https://www.action.act.gov.au/ARTS/use_Funcs.asp'; | |
//$url = 'http://localhost/myway.htm'; | |
$field_mapping = Array( | |
"card_number" => "SRNO", | |
"DOBmonth" => "month", | |
"DOBday" => "day", | |
"DOByear" => "year", | |
"secret_answer" => "pwrd", | |
"button" => "Submit" | |
); | |
foreach (Array( | |
"card_number", | |
"DOBday", | |
"DOBmonth", | |
"DOByear" | |
) as $field_name) { | |
if (isset($_REQUEST[$field_name])) { | |
$fields[$field_name] = filter_var($_REQUEST[$field_name], FILTER_SANITIZE_NUMBER_INT); | |
} | |
else { | |
$return["error"][] = $field_name. " parameter invalid or unspecified"; | |
} | |
} | |
if (isset($_REQUEST['secret_answer'])) { | |
$fields['secret_answer'] = filter_var($_REQUEST['secret_answer'], FILTER_SANITIZE_STRING, Array( | |
FILTER_FLAG_NO_ENCODE_QUOTES, | |
FILTER_FLAG_STRIP_HIGH, | |
FILTER_FLAG_STRIP_LOW | |
)); | |
} | |
else { | |
$return["error"][] = "secret_answer parameter invalid or unspecified"; | |
} | |
$fields['button'] = 'Submit'; | |
$fields_string = ""; | |
//url-ify the data for the POST | |
foreach ($fields as $key => $value) { | |
if (sizeof($value) === 0) $return['error'][] = $key . " parameter invalid or unspecified"; | |
$fields_string.= $field_mapping[$key] . '=' . $value . '&'; | |
} | |
$fields_string = rtrim($fields_string, '&'); | |
if (!isset($return['error'])) { | |
//open connection | |
$ch = curl_init(); | |
//set the url, number of POST vars, POST data | |
curl_setopt($ch, CURLOPT_URL, $url); | |
curl_setopt($ch, CURLOPT_POST, count($fields)); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_REFERER, "https://www.action.act.gov.au/ARTS/getbalance.asp"); | |
curl_setopt($ch, CURLOPT_HEADER, 0); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 30); | |
//execute post | |
$pageHTML = curl_exec($ch); | |
if (curl_errno($ch)) $return["error"][] = "Network error " . curl_errno($ch) . " " . curl_error($ch) . " " . $url . $fields_string; | |
//close connection | |
curl_close($ch); | |
} | |
if (!isset($return['error'])) { | |
include_once ('../lib/simple_html_dom.php'); | |
//print_r($pageHTML); | |
$page = str_get_html($pageHTML); | |
$pageAlerts = $page->find(".smartCardAlert"); | |
if (sizeof($pageAlerts) > 0) { | |
$return['error'][] = $pageAlerts[0]->plaintext; | |
} | |
if (!isset($return['error'])) { | |
$tableNum = 0; | |
$tableName = Array( | |
1 => "myway_carddetails", | |
2 => "myway_transactions" | |
); | |
foreach ($page->find("table") as $table) { | |
$tableNum++; | |
$tableColumns = Array(); | |
$tableColumnNum = 0; | |
foreach ($table->find("th") as $th) { | |
$tableColumns[$tableColumnNum] = cleanString($th->plaintext); | |
$tableColumnNum++; | |
} | |
//print_r($tableColumns); | |
$tableRowNum = 0; | |
foreach ($table->find("tr") as $tr) { | |
$tableColumnNum = 0; | |
foreach ($tr->find("td") as $td) { | |
if ($tableNum == 1) { | |
// first table has card/cardholder details | |
$return[$tableName[$tableNum]][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext); | |
} else { | |
// second table has transactions | |
if ($tableColumns[$tableColumnNum] == "TX Reference No / Type") { | |
$return[$tableName[$tableNum]][$tableRowNum]["TX Reference No"] = substr(cleanString($td->plaintext), 0,6); | |
$return[$tableName[$tableNum]][$tableRowNum]["TX Type"] = substr(cleanString($td->plaintext), 7); | |
} else { | |
$return[$tableName[$tableNum]][$tableRowNum][$tableColumns[$tableColumnNum]] = cleanString($td->plaintext); | |
} | |
} | |
//print_r($return); | |
$tableColumnNum++; | |
} | |
$tableRowNum++; | |
} | |
} | |
} | |
} | |
if (sizeof($return) == 0) { | |
$return['error'][] = "No data extracted from MyWay website - API may be out of date"; | |
} | |
if (basename(__FILE__) == "myway_api.json.php") { | |
header('Content-Type: text/javascript; charset=utf8'); | |
// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/'); | |
header('Access-Control-Max-Age: 3628800'); | |
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); | |
if (isset($_GET['callback'])) { | |
$json = '(' . json_encode($return) . ');'; //must wrap in parens and end with semicolon | |
print_r($_GET['callback'] . $json); //callback is prepended for json-p | |
} | |
else echo json_encode($return); | |
} | |
?> | |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Deltas", "mywayDelta"); | |
?> | |
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../js/flot/excanvas.min.js"></script><![endif]--> | |
<script language="javascript" type="text/javascript" src="../js/flot/jquery.flot.js"></script> | |
<center><div id="placeholder" style="width:900px;height:550px"></div></center> | |
<script type="text/javascript"> | |
$(function () { | |
var d = new Date(); | |
d.setUTCMinutes(0); | |
d.setUTCHours(0); | |
var midnight = d.getTime(); | |
<?php | |
$query = "select * from myway_timingdeltas where abs(timing_delta) < 2*(select stddev(timing_delta) from myway_timingdeltas) order by route_full_name;"; | |
$query = $conn -> prepare($query); | |
$query -> execute(); | |
if (!$query) { | |
databaseError($conn -> errorInfo()); | |
return Array(); | |
} | |
$i = 0; | |
$labels = Array(); | |
$lastRoute = ""; | |
foreach ($query -> fetchAll() as $delta) { | |
$routeName = $delta['route_full_name']; | |
if (strstr($routeName, " 3")) $routeName = "312-319"; | |
else $routeName = preg_replace('/\D/', '', $routeName); | |
if ($routeName != $lastRoute) { | |
$i++; | |
echo " var d$i = [];"; | |
$lastRoute = $routeName; | |
$labels[$i] = $routeName; | |
} | |
echo "d$i.push([ midnight+ (1000*" . midnight_seconds(strtotime($delta['time'])) . "), " . intval($delta['timing_delta']) . "]); \n"; | |
} ; | |
?> | |
var placeholder = $("#placeholder"); | |
var plot = $.plot(placeholder, [ | |
<?php | |
foreach ($labels as $key => $label) { | |
echo " { | |
data: d$key, | |
points: { show: true }, | |
label: '$label' | |
},"; | |
} | |
?> | |
], | |
{ | |
xaxis: { | |
mode: "time", | |
min: midnight + (1000*60*60*8), | |
max: midnight + (1000*60*60*23.5) | |
}, | |
yaxis: { | |
tickFormatter: yformatter | |
}, | |
grid: { hoverable: true, clickable: true, labelMargin: 32 }, | |
}); | |
var o; | |
o = plot.pointOffset({ x: midnight+ (9*60*60*1000), y: -1.2}); | |
placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">9am</div>'); | |
o = plot.pointOffset({ x: midnight+ (16*60*60*1000), y: -1.2}); | |
placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">4pm</div>'); | |
}); | |
function yformatter(v) { | |
if (Math.floor(v/60) < -9) return ""; | |
return Math.abs(Math.floor(v/60)) + " min " + (v == 0 ? "" : (v >0 ? "early":"late")) | |
} | |
function showTooltip(x, y, contents) { | |
$('<div id="tooltip">' + contents + '</div>').css( { | |
position: 'absolute', | |
display: 'none', | |
top: y + 5, | |
left: x + 5, | |
border: '1px solid #fdd', | |
padding: '2px', | |
'background-color': '#fee', | |
opacity: 0.80 | |
}).appendTo("body").fadeIn(200); | |
} | |
var previousPoint = null; | |
$("#placeholder").bind("plothover", function (event, pos, item) { | |
$("#x").text(pos.x.toFixed(2)); | |
$("#y").text(pos.y.toFixed(2)); | |
if (item) { | |
if (previousPoint != item.dataIndex) { | |
previousPoint = item.dataIndex; | |
$("#tooltip").remove(); | |
var x = item.datapoint[0].toFixed(2), | |
y = item.datapoint[1].toFixed(2); | |
var d = new Date(); | |
d.setTime(x); | |
var time = d.getUTCHours() +':'+ (d.getUTCMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getUTCMinutes()) | |
showTooltip(item.pageX, item.pageY, | |
item.series.label + " at "+ time +" = " + Math.abs(new Number(y/60).toFixed(2))+" minutes "+(y >0 ? "early":"late")); | |
} | |
} | |
else { | |
$("#tooltip").remove(); | |
previousPoint = null; | |
} | |
}); | |
</script> |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Delta Calculate", "mywayDeltaCalc"); | |
flush(); | |
ob_flush(); | |
function abssort($a, $b) | |
{ | |
if ($a['timeDiff'] == $b['timeDiff']) { | |
return 0; | |
} | |
return (abs($a['timeDiff']) < abs($b['timeDiff'])) ? -1 : 1; | |
} | |
//collect all observation not in delta | |
$query = "select * from myway_observations INNER JOIN myway_stops | |
ON myway_observations.myway_stop=myway_stops.myway_stop INNER JOIN myway_routes | |
ON myway_observations.myway_route=myway_routes.myway_route | |
WHERE observation_id NOT IN | |
( | |
SELECT observation_id | |
FROM myway_timingdeltas | |
)"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
$uncalcdObservations = $query->fetchAll(); | |
//Display count | |
echo "<h3>" . sizeof($uncalcdObservations) . " observations not yet processed</h2>"; | |
//foreach observation not in delta | |
foreach ($uncalcdObservations as $obsv) { | |
//var_dump($obsv); | |
echo "<h3>Observation {$obsv['observation_id']}:</h1> | |
<small>{$obsv['myway_stop']} @ {$obsv['time']} on {$obsv['myway_route']}</small><br>"; | |
if ($obsv["stop_code"] == "") { | |
echo "error, stop '{$obsv['myway_stop']}' unknown"; | |
continue; | |
} | |
if ($obsv["route_full_name"] == "") { | |
echo "error, route '{$obsv['myway_route']}' unknown"; | |
continue; | |
} | |
// convert timestamp into time of day and date | |
// timezones from http://www.postgresql.org/docs/8.0/static/datetime-keywords.html | |
$time = date("H:i:s", strtotime($obsv['time'])); | |
$time_tz = date("H:i:s", strtotime($obsv['time']))." AESST"; | |
$search_time = date("H:i:s", strtotime($obsv['time'])-(30*60)); // 30 minutes margin | |
$date = date("c", strtotime($obsv['time'])); | |
$timing_period = service_period(strtotime($date)); | |
$potentialStops = getStopsByStopCode($obsv["stop_code"], $obsv["stop_street"]); | |
//:get myway_stops records | |
//:search by starts with stopcode and starts with street if street is not null | |
//no result, skip and display error | |
if (sizeof($potentialStops) < 1) { | |
echo "error, potential stops for stopcode {$obsv["stop_code"]} street {$obsv["stop_street"]} unknown"; | |
continue; | |
} | |
//print out stops | |
echo "Matched stops: "; | |
foreach ($potentialStops as $potentialStop) echo $potentialStop['stop_code'] . " "; | |
echo "<br>"; | |
//:get myway_route record | |
//no result, skip and display error | |
//print out route | |
$potentialRoute = getRouteByFullName($obsv["route_full_name"]); | |
if ($potentialRoute["route_short_name"] == "") { | |
echo "error, route '{$obsv["route_full_name"]}' unknown"; | |
continue; | |
} | |
echo "Matched route: {$potentialRoute['route_short_name']}{$potentialRoute['route_long_name']} {$timing_period}<br>"; | |
$timeDeltas = Array(); | |
foreach ($potentialStops as $potentialStop) { | |
$stopRoutes = getStopRoutes($potentialStop['stop_id'], $timing_period); | |
$foundRoute = Array(); | |
foreach ($stopRoutes as $stopRoute) { | |
//Check if this route stops at each stop | |
if ($stopRoute['route_short_name'] . $stopRoute['route_long_name'] == $obsv["route_full_name"]) { | |
echo "Matching route {$stopRoute['route_id']} found at {$potentialStop['stop_code']}<br>"; | |
$foundRoute = $stopRoute; | |
//if does get tripstoptimes for this route | |
$trips = getStopTrips($potentialStop['stop_id'], $timing_period, $search_time); | |
foreach ($trips as $trip) { | |
//echo $trip['route_id']." ".$stopRoute['route_id'].";"; | |
if ($trip['route_id'] == $stopRoute['route_id']) { | |
$timedTrip = getTimeInterpolatedTripAtStop($trip['trip_id'], $trip['stop_sequence']); | |
$actual_time = strtotime($time); | |
$trip_time = strtotime($timedTrip['arrival_time']); | |
$timeDiff = $actual_time - $trip_time; | |
//work out time delta, put into array with index of delta | |
$timeDeltas[] = Array( | |
"timeDiff" => $timeDiff, | |
"stop_code" => $potentialStop['stop_code'], | |
"stop_sequence" => $timedTrip['stop_sequence'] | |
); | |
echo "Found trip {$trip['trip_id']} at stop {$potentialStop['stop_code']} (#{$potentialStop['stop_id']}, sequence #{$trip['stop_sequence']})<br>"; | |
echo "Arriving at {$timedTrip['arrival_time']}, difference of " . round($timeDiff / 60, 2) . " minutes<br>"; | |
} | |
} | |
break; // because have found route | |
} | |
} | |
if (sizeof($foundRoute) < 1) { | |
//print out that stops/does not stop | |
echo "No matching routes found at {$potentialStop['stop_code']}<br>"; | |
var_dump($stopRoutes); | |
flush(); | |
} | |
} | |
// lowest delta is recorded delta | |
usort($timeDeltas, "abssort"); | |
$lowestDelta = $timeDeltas[0]["timeDiff"]; | |
if (sizeof($timeDeltas) != 0) { | |
echo "Lowest difference of " . round($lowestDelta / 60, 2) . " minutes will be recorded for this observation<br>"; | |
$observation_id = $obsv['observation_id']; | |
$route_full_name = $obsv['route_full_name']; | |
$stop_code = $timeDeltas[0]["stop_code"]; | |
$stop_sequence = $timeDeltas[0]["stop_sequence"]; | |
$stmt = $conn->prepare("insert into myway_timingdeltas (observation_id, route_full_name, stop_code, timing_delta, time, date, timing_period, stop_sequence) | |
values (:observation_id, :route_full_name, :stop_code, :timing_delta, :time, :date, :timing_period, :stop_sequence)"); | |
$stmt->bindParam(':observation_id', $observation_id); | |
$stmt->bindParam(':route_full_name', $route_full_name); | |
$stmt->bindParam(':stop_code', $stop_code); | |
$stmt->bindParam(':timing_delta', $lowestDelta); | |
$stmt->bindParam(':time', $time_tz); | |
$stmt->bindParam(':date', $date); | |
$stmt->bindParam(':timing_period', $timing_period); | |
$stmt->bindParam(':stop_sequence', $stop_sequence); | |
// insert a record | |
$stmt->execute(); | |
if ($stmt->rowCount() > 0) { | |
echo "Recorded.<br>"; | |
} | |
var_dump($conn->errorInfo()); | |
flush(); | |
} | |
flush(); | |
} | |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Deltas", "mywayDelta"); | |
?> | |
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../js/flot/excanvas.min.js"></script><![endif]--> | |
<script language="javascript" type="text/javascript" src="../js/flot/jquery.flot.js"></script> | |
<center><div id="placeholder" style="width:900px;height:550px"></div></center> | |
<script type="text/javascript"> | |
$(function () { | |
var d1 = []; | |
<?php | |
$query = "select td, count(*) from (select (timing_delta - MOD(timing_delta,10)) as td from myway_timingdeltas where abs(timing_delta) < 2*(select stddev(timing_delta) from myway_timingdeltas)) as a group by td order by td"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $delta) { | |
echo "d1.push([ ".intval($delta['td']).", ".intval($delta['count'])."]); \n"; | |
}; | |
?> | |
var placeholder = $("#placeholder"); | |
var plot = $.plot(placeholder, [ | |
{ | |
data: d1, | |
bars: { show: true } | |
}, | |
], | |
{ | |
grid: { hoverable: true, clickable: true, labelMargin: 17 }, | |
}); | |
}); | |
</script> |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Deltas", "mywayDelta"); | |
?> | |
<table> | |
<tr><td></td><td>Mean</td><td>Standard<br>Deviation</td><td>Sample Size</td></tr> | |
<th> Overall </th> | |
<?php | |
$query = "select '', avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas "; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $row) { | |
echo "<tr><td>{$row[0]}</td><td>" . floor($row[1]) . "</td><td>" . floor($row[2]) . "</td><td>{$row[3]}</td></tr>"; | |
}; | |
?> | |
<th> Hour of Day </th> | |
<?php | |
$query = "select extract(hour from time), avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas group by extract(hour from time) order by extract(hour from time)"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $row) { | |
echo "<tr><td>{$row[0]}</td><td>" . floor($row[1]) . "</td><td>" . floor($row[2]) . "</td><td>{$row[3]}</td></tr>"; | |
}; | |
?> | |
<th> Day of Week </th> | |
<?php | |
$query = "select to_char(date, 'Day'), avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas group by to_char(date, 'Day') order by to_char(date, 'Day')"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $row) { | |
echo "<tr><td>{$row[0]}</td><td>" . floor($row[1]) . "</td><td>" . floor($row[2]) . "</td><td>{$row[3]}</td></tr>"; | |
}; | |
?> | |
<th>Month </th> | |
<?php | |
$query = "select to_char(date, 'Month'), avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas group by to_char(date, 'Month') order by to_char(date, 'Month')"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $row) { | |
echo "<tr><td>{$row[0]}</td><td>" . floor($row[1]) . "</td><td>" . floor($row[2]) . "</td><td>{$row[3]}</td></tr>"; | |
}; | |
?> | |
<th>Stop </th> | |
<?php | |
$query = "select myway_stop, avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas INNER JOIN myway_observations | |
ON myway_observations.observation_id=myway_timingdeltas.observation_id group by myway_stop having count(*) > 1 order by myway_stop"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $row) { | |
echo "<tr><td>{$row[0]}</td><td>" . floor($row[1]) . "</td><td>" . floor($row[2]) . "</td><td>{$row[3]}</td></tr>"; | |
}; | |
?> | |
<th>Route </th> | |
<?php | |
$query = "select route_full_name, avg(timing_delta), stddev(timing_delta), count(*) from myway_timingdeltas group by route_full_name having count(*) > 1 order by route_full_name"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $row) { | |
echo "<tr><td>{$row[0]}</td><td>" . floor($row[1]) . "</td><td>" . floor($row[2]) . "</td><td>{$row[3]}</td></tr>"; | |
}; | |
?> | |
</table> | |
<?php | |
include_footer(); | |
?> | |
<?php | |
include ('../include/common.inc.php'); | |
auth(); | |
foreach ($_REQUEST as $key => $value) { | |
if (strstr($key, "route") && !strstr($value, "Select")) { | |
$myway_route = str_replace("route", "", $key); | |
$route_full_name = $value; | |
$query = "update myway_routes set route_full_name = :route_full_name where myway_route = :myway_route"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->bindParam(":myway_route", $myway_route,PDO::PARAM_STR, 5); | |
$query->bindParam(":route_full_name", $route_full_name,PDO::PARAM_STR, 42); | |
$query->execute(); | |
die(print_r($conn->errorInfo() , true)); | |
} | |
if (strstr($key, "myway_stop")) { | |
$myway_stop = $value; | |
$stop_code = $_REQUEST['stop_code']; | |
$stop_street = $_REQUEST['stop_street']; | |
$query = "update myway_stops set stop_code = :stop_code, stop_street = :stop_street where myway_stop = :myway_stop"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->bindParam(":myway_stop", $myway_stop, PDO::PARAM_STR, 25); | |
$query->bindParam(":stop_code", $stop_code, PDO::PARAM_STR, 32); | |
$query->bindParam(":stop_street", $stop_street); | |
$query->execute(); | |
die(print_r($conn->errorInfo() , true)); | |
} | |
} | |
include_header("MyWay Data Reconcile", "mywayTimeRec"); | |
// initialise | |
$count = $conn->exec("insert into myway_stops | |
select distinct myway_stop from myway_observations | |
WHERE myway_stop NOT IN | |
( | |
SELECT myway_stop | |
FROM myway_stops | |
)"); | |
echo "$count new stops.<br>"; | |
if (!$count) { | |
print_r($conn->errorInfo()); | |
} | |
$count = $conn->exec("insert into myway_routes select distinct myway_route from myway_observations | |
WHERE myway_route NOT IN | |
( | |
SELECT myway_route | |
FROM myway_routes | |
)"); | |
echo "$count new routes.<br>"; | |
if (!$count) { | |
print_r($conn->errorInfo()); | |
} | |
echo "<h2>Stops</h2>"; | |
/*stops | |
search start of name, display map and table nuimbered, two text boxes */ | |
$query = "Select * from myway_stops where stop_code is NULL and stop_street is NUll;"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $myway_stop) { | |
echo "<h3>{$myway_stop[0]}</h3>"; | |
$stopNameParts = explode(" ", $myway_stop[0]); | |
$markers = array(); | |
$stopKey = 1; | |
$foundStops = getStops(false, "", $stopNameParts[0] . " " . $stopNameParts[1]); | |
if (sizeof($foundStops) > 0) { | |
echo "<table>"; | |
foreach ($foundStops as $stopResult) { | |
$markers[] = array( | |
$stopResult['stop_lat'], | |
$stopResult['stop_lon'] | |
); | |
echo "<tr><td>" . $stopKey++ . "</td><td>" . $stopResult['stop_name'] . "</td><td>" . $stopResult['stop_code'] . "</td></tr>"; | |
} | |
echo '</table>'; | |
echo "" . staticmap($markers, 0, "icong", false) . "<br>\n"; | |
} | |
echo '<form id="inputform' .md5($myway_stop[0]).'"> | |
<input type="hidden" name="myway_stop" value="' .$myway_stop[0].'"> | |
<div data-role="fieldcontain"> | |
<label for="stop_code">Stop Code</label> | |
<input type="text" name="stop_code" id="stop_code" value="' . $foundStops[0]['stop_code'] . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="stop_street">Stop Street </label> | |
<input type="text" name="stop_street" id="stop_street" value="' . $foundStops[0]['stop_name'] . '" /> | |
</div> <input type="button" onclick="$.post(\'myway_timeliness_reconcile.php\', $(\'#inputform' .md5($myway_stop[0]) . '\').serialize())" value="Go!"></form> | |
'; | |
echo '<hr>'; | |
} | |
echo '<h2>Routes</h2>'; | |
/*routes | |
remove alpha char, search present dropdown*/ | |
$query = "Select * from myway_routes where route_full_name is NUll;"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $myway_route) { | |
echo "<h3>{$myway_route[0]}</h3>"; | |
$query = "Select * from myway_observations where myway_route = :route order by time"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->bindParam(":route", $myway_route[0]); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $myway_obvs) { | |
echo $myway_obvs['myway_stop'] . $myway_obvs['time'] . "<br>"; | |
} | |
$searchRouteNo = preg_replace("/[A-Z]/", "", $myway_route[0]); | |
echo $searchRouteNo; | |
echo '<form id="inputform' . $myway_route[0] . '"> | |
<select name="route' . $myway_route[0] . '" onchange=\'$.post("myway_timeliness_reconcile.php", $("#inputform' . $myway_route[0] . '").serialize())\'> | |
<option>Select a from/to pair...</option>'; | |
foreach (getRoutesByNumber($searchRouteNo) as $routeResult) { | |
echo "<option value=\"{$routeResult['route_short_name']}{$routeResult['route_long_name']}\"> {$routeResult['route_short_name']}{$routeResult['route_long_name']} </option>\n"; | |
} | |
echo "</select></form>"; | |
echo '<hr>'; | |
} | |
include_footer(); | |
?> | |
<?php | |
include ('../include/common.inc.php'); | |
header('Content-Type: text/javascript; charset=utf8'); | |
// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/'); | |
header('Access-Control-Max-Age: 3628800'); | |
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); | |
?> | |
{ | |
"label": "<?php echo $_REQUEST['routeid']; ?>", | |
"data": <?php | |
$query = "select * from myway_timingdeltas where route_full_name = :route_full_name AND abs(timing_delta) < 2*(select stddev(timing_delta) from myway_timingdeltas) order by stop_sequence;"; | |
$query = $conn->prepare($query); | |
$query->bindParam(':route_full_name', $_REQUEST['routeid'],PDO::PARAM_STR, 42); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $delta) { | |
$points[] = "[{$delta['stop_sequence']}, {$delta['timing_delta']}]"; | |
}; | |
echo "[".implode(",",$points)."]"; | |
?> | |
} |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Deltas", "mywayDelta"); | |
?> | |
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../js/flot/excanvas.min.js"></script><![endif]--> | |
<script language="javascript" type="text/javascript" src="../js/flot/jquery.flot.js"></script> | |
<form method="get" action=""> | |
<select id="routeid" name="routeid"> | |
<?php | |
$query = "select distinct route_full_name from myway_routes where myway_route != '' order by route_full_name"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $route) { | |
echo "<option value=\"{$route['route_full_name']}\">{$route['route_full_name']}</option>"; | |
}; | |
?> </select> | |
<center><div id="placeholder" style="width:900px;height:550px"></div></center> | |
<script type="text/javascript"> | |
$(function () { | |
var placeholder = $("#placeholder"); | |
var data = []; | |
var options = { | |
xaxis: { | |
}, | |
yaxis: { | |
tickFormatter: yformatter | |
}, | |
grid: { hoverable: true, clickable: true, labelMargin: 32 }, | |
series: { | |
lines: { show: false }, | |
points: { show: true } | |
} | |
}; | |
var plot = $.plot(placeholder, data, options); | |
// fetch one series, adding to what we got | |
var alreadyFetched = {}; | |
$("#routeid").change(function () { | |
var select = $(this); | |
// find the URL in the link right next to us | |
// var dataurl = button.siblings('a').attr('href'); | |
var dataurl = "myway_timeliness_route.json.php?routeid=" + select.val(); | |
// then fetch the data with jQuery | |
function onDataReceived(series) { | |
// extract the first coordinate pair so you can see that | |
// data is now an ordinary Javascript object | |
var firstcoordinate = '(' + series.data[0][0] + ', ' + series.data[0][1] + ')'; | |
// let's add it to our current data | |
if (!alreadyFetched[series.label]) { | |
alreadyFetched[series.label] = true; | |
data.push(series); | |
} | |
// and plot all we got | |
$.plot(placeholder, data, options); | |
} | |
$.ajax({ | |
url: dataurl, | |
method: 'GET', | |
dataType: 'json', | |
success: onDataReceived | |
}); | |
}); | |
}); | |
function yformatter(v) { | |
if (Math.floor(v/60) < -9) return ""; | |
return Math.abs(Math.floor(v/60)) + " min " + (v == 0 ? "" : (v >0 ? "early":"late")) | |
} | |
function showTooltip(x, y, contents) { | |
$('<div id="tooltip">' + contents + '</div>').css( { | |
position: 'absolute', | |
display: 'none', | |
top: y + 5, | |
left: x + 5, | |
border: '1px solid #fdd', | |
padding: '2px', | |
'background-color': '#fee', | |
opacity: 0.80 | |
}).appendTo("body").fadeIn(200); | |
} | |
var previousPoint = null; | |
$("#placeholder").bind("plothover", function (event, pos, item) { | |
$("#x").text(pos.x.toFixed(2)); | |
$("#y").text(pos.y.toFixed(2)); | |
if (item) { | |
if (previousPoint != item.dataIndex) { | |
previousPoint = item.dataIndex; | |
$("#tooltip").remove(); | |
var x = item.datapoint[0], | |
y = item.datapoint[1].toFixed(2); | |
showTooltip(item.pageX, item.pageY, | |
item.series.label + " at stop_sequence "+ x +" = " + Math.abs(new Number(y/60).toFixed(2))+" minutes "+(y >0 ? "early":"late")); | |
} | |
} | |
else { | |
$("#tooltip").remove(); | |
previousPoint = null; | |
} | |
}); | |
</script> | |
<?php | |
include ('../include/common.inc.php'); | |
header('Content-Type: text/javascript; charset=utf8'); | |
// header('Access-Control-Allow-Origin: http://bus.lambdacomplex.org/'); | |
header('Access-Control-Max-Age: 3628800'); | |
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); | |
?> | |
{ | |
"label": "<?php echo $_REQUEST['stopid']; ?>", | |
"data": <?php | |
$query = "select * from myway_timingdeltas INNER JOIN myway_observations | |
ON myway_observations.observation_id=myway_timingdeltas.observation_id | |
where myway_stop = :myway_stop | |
AND abs(timing_delta) < 2*(select stddev(timing_delta) from myway_timingdeltas) | |
order by myway_timingdeltas.time;"; | |
$query = $conn->prepare($query); | |
$query->bindParam(':myway_stop', $_REQUEST['stopid'],PDO::PARAM_STR, 42); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $delta) { | |
$points[] = "[".((strtotime("00:00Z") + midnight_seconds(strtotime($delta['time'])))*1000).", {$delta['timing_delta']}]"; | |
}; | |
if (count($points) == 0) { | |
echo "[]"; } | |
else echo "[".implode(",",$points)."]"; | |
?> | |
} | |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Deltas", "mywayDelta"); | |
?> | |
<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="../js/flot/excanvas.min.js"></script><![endif]--> | |
<script language="javascript" type="text/javascript" src="../js/flot/jquery.flot.js"></script> | |
<form method="get" action=""> | |
<select id="stopid" name="stopid"> | |
<?php | |
$query = "select distinct myway_stop from myway_stops where myway_stop != '' order by myway_stop"; | |
$query = $conn->prepare($query); | |
$query->execute(); | |
if (!$query) { | |
databaseError($conn->errorInfo()); | |
return Array(); | |
} | |
foreach ($query->fetchAll() as $stop) { | |
echo "<option value=\"{$stop['myway_stop']}\">{$stop['myway_stop']}</option>"; | |
}; | |
?> </select> <center><div id="placeholder" style="width:900px;height:550px"></div></center> | |
<script type="text/javascript"> | |
$(function () { | |
var d = new Date(); | |
d.setUTCMinutes(0); | |
d.setUTCHours(0); | |
var midnight = d.getTime(); | |
var placeholder = $("#placeholder"); | |
var data = []; | |
var options = { | |
xaxis: { | |
mode: "time", | |
min: midnight + (1000*60*60*8), | |
max: midnight + (1000*60*60*23.5) | |
}, | |
yaxis: { | |
tickFormatter: yformatter | |
}, | |
grid: { hoverable: true, clickable: true, labelMargin: 32 }, | |
series: { | |
lines: { show: false }, | |
points: { show: true } | |
} | |
}; | |
var plot = $.plot(placeholder, data, options); | |
var o; | |
o = plot.pointOffset({ x: midnight+ (9*60*60*1000), y: -1.2}); | |
placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">9am</div>'); | |
o = plot.pointOffset({ x: midnight+ (16*60*60*1000), y: -1.2}); | |
placeholder.append('<div style="position:absolute;left:' + (o.left + 4) + 'px;top:' + o.top + 'px;color:#666;font-size:smaller">4pm</div>'); | |
// fetch one series, adding to what we got | |
var alreadyFetched = {}; | |
$("#stopid").change(function () { | |
var select = $(this); | |
// find the URL in the link right next to us | |
// var dataurl = button.siblings('a').attr('href'); | |
var dataurl = "myway_timeliness_stop.json.php?stopid=" + select.val(); | |
// then fetch the data with jQuery | |
function onDataReceived(series) { | |
// extract the first coordinate pair so you can see that | |
// data is now an ordinary Javascript object | |
var firstcoordinate = '(' + series.data[0][0] + ', ' + series.data[0][1] + ')'; | |
// let's add it to our current data | |
if (!alreadyFetched[series.label]) { | |
alreadyFetched[series.label] = true; | |
data.push(series); | |
} | |
// and plot all we got | |
$.plot(placeholder, data, options); | |
} | |
$.ajax({ | |
url: dataurl, | |
method: 'GET', | |
dataType: 'json', | |
success: onDataReceived | |
}); | |
}); | |
}); | |
function yformatter(v) { | |
if (Math.floor(v/60) < -9) return ""; | |
return Math.abs(Math.floor(v/60)) + " min " + (v == 0 ? "" : (v >0 ? "early":"late")) | |
} | |
function showTooltip(x, y, contents) { | |
$('<div id="tooltip">' + contents + '</div>').css( { | |
position: 'absolute', | |
display: 'none', | |
top: y + 5, | |
left: x + 5, | |
border: '1px solid #fdd', | |
padding: '2px', | |
'background-color': '#fee', | |
opacity: 0.80 | |
}).appendTo("body").fadeIn(200); | |
} | |
var previousPoint = null; | |
$("#placeholder").bind("plothover", function (event, pos, item) { | |
$("#x").text(pos.x.toFixed(2)); | |
$("#y").text(pos.y.toFixed(2)); | |
if (item) { | |
if (previousPoint != item.dataIndex) { | |
previousPoint = item.dataIndex; | |
$("#tooltip").remove(); | |
var x = item.datapoint[0].toFixed(2), | |
y = item.datapoint[1].toFixed(2); | |
var d = new Date(); | |
d.setTime(x); | |
var time = d.getUTCHours() +':'+ (d.getUTCMinutes().toString().length == 1 ? '0'+ d.getMinutes(): d.getUTCMinutes()) | |
showTooltip(item.pageX, item.pageY, | |
item.series.label + " at "+ time +" = " + Math.abs(new Number(y/60).toFixed(2))+" minutes "+(y >0 ? "early":"late")); | |
} | |
} | |
else { | |
$("#tooltip").remove(); | |
previousPoint = null; | |
} | |
}); | |
</script> | |
<?php | |
include ('../include/common.inc.php'); | |
include_header("MyWay Balance", "mywayBalance", false, false, true); | |
echo '<div data-role="page"> | |
<div data-role="header" data-position="inline"> | |
<a href="' . $_SERVER["HTTP_REFERER"] . '" data-icon="arrow-l" data-rel="back" class="ui-btn-left">Back</a> | |
<h1>MyWay Balance</h1> | |
<a href="mywaybalance.php?logout=yes" data-icon="delete" class="ui-btn-right">Logout</a> | |
</div><!-- /header --> | |
<a name="maincontent" id="maincontent"></a> | |
<div data-role="content"> '; | |
$return = Array(); | |
function logout() | |
{ | |
setcookie("card_number", "", time() - 60 * 60 * 24 * 100, "/"); | |
setcookie("date", "", time() - 60 * 60 * 24 * 100, "/"); | |
setcookie("secret_answer", "", time() - 60 * 60 * 24 * 100, "/"); | |
setcookie("contribute_myway", "", time() - 60 * 60 * 24 * 100, "/"); | |
} | |
function printBalance($mywayResult) | |
{ | |
if (isset($mywayResult['error'])) { | |
logout(); | |
echo '<h3><font color="red">' . $mywayResult['error'][0] . "</font></h3>"; | |
} | |
else { | |
echo "<h2>Balance: " . $mywayResult['myway_carddetails']['Card Balance'] . "</h2>"; | |
echo '<ul data-role="listview" data-inset="true"><li data-role="list-divider"> Recent Transactions </li>'; | |
$txCount = 0; | |
foreach ($mywayResult['myway_transactions'] as $transaction) { | |
echo "<li>"; | |
if ($transaction["Deduction Type"] == "DEFAULT") echo '<img src="css/images/warning.png" alt="Failed to tap off: " class="ui-li-icon">'; | |
echo "<b>" . $transaction["Date / Time"] . "</b>"; | |
echo "<br><small>" . $transaction["Route"] . " at " . $transaction["Stop Name"] . "<br>"; | |
echo $transaction["TX Reference No"] . " " . $transaction["TX Type"] . "</small>"; | |
echo '<p class="ui-li-aside">' . $transaction["TX Amount"] . '</p>'; | |
echo "</li>"; | |
$txCount++; | |
if ($txCount > 10) break; | |
} | |
echo "</ul>"; | |
} | |
} | |
function recordMyWayObservations($mywayResult) | |
{ | |
global $conn; | |
if (!isset($mywayResult['error'])) { | |
$stmt = $conn->prepare("insert into myway_observations (observation_id, myway_stop, time, myway_route) | |
values (:observation_id, :myway_stop, :time, :myway_route)"); | |
$stmt->bindParam(':observation_id', $observation_hash); | |
$stmt->bindParam(':myway_stop', $myway_stop); | |
$stmt->bindParam(':time', $timestamp); | |
$stmt->bindParam(':myway_route', $myway_route); | |
// insert a record | |
$resultCount = 0; | |
foreach ($mywayResult['myway_transactions'] as $transaction) { | |
if ($transaction["Stop Name"] != "" && $transaction["Deduction Type"] != "DEFAULT") { | |
$observation_hash = md5($mywayResult['myway_carddetails']['MyWay Number'] . $transaction["TX Reference No"]); | |
$timestamp = date("c", strtotime($transaction["Date / Time"])); | |
$myway_stop = $transaction["Stop Name"]; | |
$myway_route = $transaction["Route"]; | |
if ($stmt->execute()) $resultCount++; | |
} | |
} | |
echo "<h3>Thanks for participating in the study! $resultCount transactions were recorded</h3>"; | |
} | |
} | |
if (isset($_REQUEST['card_number']) && isset($_REQUEST['date']) && isset($_REQUEST['secret_answer'])) { | |
$cardNumber = $_REQUEST['card_number']; | |
$date = explode("/", $_REQUEST['date']); | |
$pwrd = $_REQUEST['secret_answer']; | |
if ($_REQUEST['remember'] == "on") { | |
setcookie("card_number", $cardNumber, time() + 60 * 60 * 24 * 100, "/"); | |
setcookie("date", $_REQUEST['date'], time() + 60 * 60 * 24 * 100, "/"); | |
setcookie("contribute_myway", $_REQUEST['contribute_myway'], time() + 60 * 60 * 24 * 100, "/"); | |
setcookie("secret_answer", $pwrd, time() + 60 * 60 * 24 * 100, "/"); | |
} | |
$mywayResult = json_decode(getPage(curPageURL() . "/myway_api.json.php?card_number=$cardNumber&DOBday={$date[0]}&DOBmonth={$date[1]}&DOByear={$date[2]}&secret_answer=$pwrd") , true); | |
if ($_REQUEST['contribute_myway'] == "on") recordMyWayObservations($mywayResult); | |
printBalance($mywayResult); | |
} | |
else if (isset($_REQUEST['logout'])) { | |
echo '<center><h3> Logged out of MyWay balance </h3><a href="/index.php">Back to main menu...</a><center>'; | |
} | |
else if (isset($_COOKIE['card_number']) && isset($_COOKIE['date']) && isset($_COOKIE['secret_answer'])) { | |
$cardNumber = $_COOKIE['card_number']; | |
$date = explode("/", $_COOKIE['date']); | |
$pwrd = $_COOKIE['secret_answer']; | |
$mywayResult = json_decode(getPage(curPageURL() . "/myway_api.json.php?card_number=$cardNumber&DOBday={$date[0]}&DOBmonth={$date[1]}&DOByear={$date[2]}&secret_answer=$pwrd") , true); | |
if ($_COOKIE['contribute_myway'] == "on") recordMyWayObservations($mywayResult); | |
printBalance($mywayResult); | |
} | |
else { | |
$date = (isset($_REQUEST['date']) ? filter_var($_REQUEST['date'], FILTER_SANITIZE_STRING) : date("m/d/Y")); | |
echo '<form action="" method="post"> | |
<div data-role="fieldcontain"> | |
<label for="card_number">Card number</label> | |
<input type="text" name="card_number" id="card_number" value="' . $card_number . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="date"> Date of birth </label> | |
<input type="text" name="date" id="date" value="' . $date . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="secret_answer"> Secret question answer </label> | |
<input type="text" name="secret_answer" id="secret_answer" value="' . $secret_answer . '" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="remember"> Remember these details? </label> | |
<input type="checkbox" name="remember" id="remember" checked="yes" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="contribute_myway">Contribute MyWay records to timeliness study? </label> | |
<input type="checkbox" name="contribute_myway" id="contribute_myway" defaultChecked="no" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="accept_warning">I accept that Transport for Canberra <a href="http://transport.act.gov.au/myway/protect.html">advise against the use of third party MyWay applications</a> </label> | |
<input type="checkbox" name="accept_warning" id="accept_warning" defaultChecked="no" /> | |
</div> | |
<input type="submit" value="Go!"></form>'; | |
} | |
include_footer(); | |
?> | |
<?php | |
include ('../include/common.inc.php'); | |
auth(); | |
include_header("Service Alert Editor", "serviceAlertEditor"); | |
/** | |
* Currently support: | |
* network inform | |
* stop remove: trip patch, route inform | |
* - stop search | |
* street inform: route inform, trip inform, stop inform | |
* - street search | |
* trip remove: route patch, stop inform | |
* - trip search by route | |
*/ | |
if (isset($_REQUEST['saveedit'])) { | |
if ($_REQUEST['saveedit'] != "") updateServiceAlert($_REQUEST['saveedit'], $_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']); | |
else addServiceAlert($_REQUEST['startdate'], $_REQUEST['enddate'], $_REQUEST['description'], $_REQUEST['url']); | |
echo "Saved " . $_REQUEST['saveedit']; | |
die(); | |
} | |
if ($_REQUEST['delete']) { | |
$deleteParts = explode(";", $_REQUEST['delete']); | |
deleteInformedAlert($deleteParts[0], $deleteParts[1], $deleteParts[2]); | |
echo "Deleted network inform for {$deleteParts[0]} ({$deleteParts[1]},{$deleteParts[2]})<br>\n"; | |
die(); | |
} | |
if ($_REQUEST['networkinform']) { | |
addInformedAlert($_REQUEST['networkinform'], "network", "network", "inform"); | |
echo "Added network inform for" . $_REQUEST['networkinform']; | |
die(); | |
} | |
if ($_REQUEST['stopsearch']) { | |
addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove"); | |
echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n"; | |
foreach ($service_periods as $sp) { | |
echo "Patching $sp trips<br>\n"; | |
foreach (getStopTrips($_REQUEST['stopid'], $sp) as $trip) { | |
addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch"); | |
echo "Added trip patch for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n"; | |
} | |
echo "Informing $sp routes<br>\n"; | |
foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) { | |
addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform"); | |
echo "Added route inform for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n"; | |
} | |
} | |
die(); | |
} | |
if ($_REQUEST['routesearch']) { | |
echo "Informing route<br>\n"; | |
$stops = Array(); | |
echo "Informing trips<br>\n"; | |
foreach(getRouteTrips() as $trip) { | |
addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch"); | |
echo "Added trip patch for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n"; | |
viaPoints($tripID, "", false); | |
} | |
echo "Informing stops<br>\n"; | |
foreach($stops as $stop) { | |
addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove"); | |
echo "Added stop remove for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n"; | |
} | |
die(); | |
} | |
if ($_REQUEST['streetsearch']) { | |
echo "Informing stops<br>\n"; | |
foreach(getStopByName() as $stop) { | |
addInformedAlert($_REQUEST['stopsearch'], "stop", $_REQUEST['stopid'], "remove"); | |
echo "Added stop inform for" . $_REQUEST['stopsearch'] . ", stop" . $_REQUEST['stopid'] . "<br>\n"; | |
foreach ($service_periods as $sp) { | |
echo "Patching $sp trips<br>\n"; | |
foreach (getStopTrips($_REQUEST['stopid'], $sp) as $trip) { | |
addInformedAlert($_REQUEST['stopsearch'], "trip", $trip['trip_id'], "patch"); | |
echo "Added trip inform for" . $_REQUEST['stopsearch'] . ", trip" . $trip['trip_id'] . "<br>\n"; | |
} | |
echo "Informing $sp routes<br>\n"; | |
foreach (getStopRoutes($_REQUEST['stopid'], $sp) as $route) { | |
addInformedAlert($_REQUEST['stopsearch'], "route", $route['route_id'], "inform"); | |
echo "Added route inform for" . $_REQUEST['stopsearch'] . ", route" . $route['route_id'] . "<br>\n"; | |
} | |
} | |
die(); | |
} | |
} | |
?> | |
Active and Future Alerts: | |
<table> | |
<?php | |
foreach(getFutureAlerts() as $alert) { | |
echo "<tr><td>{$alert['start']}</td><td>{$alert['end']}</td><td>" . substr($alert['description'], 0, 999) . '</td><td><a href="?edit=' . $alert['id'] . '">edit</a></td></tr>'; | |
} | |
?> | |
</table> | |
<?php | |
$alert = getServiceAlert($_REQUEST['edit']); | |
?> | |
<form action="<?php echo basename(__FILE__) ; | |
?>" method="get"> | |
<div data-role="fieldcontain"> | |
<label for="startdate"> Start Date</label> | |
<input type="text" name="startdate" id="startdate" value="<?php | |
if ($alert['start']) echo $alert['start']; | |
else echo date("c", strtotime("0:00")); | |
?>" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="enddate"> End Date </label> | |
<input type="text" name="enddate" id="enddate" value="<?php | |
if ($alert['end']) echo $alert['end']; | |
else echo date("c", strtotime("23:59")); | |
?>" /> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="description">Description</label> | |
<textarea name="description"> | |
<?php echo $alert['description']; | |
?></textarea> | |
</div> | |
<div data-role="fieldcontain"> | |
<label for="url">URL</label> | |
<input type="text" name="url" id="url" value="<?php echo $alert['url']; | |
?>" /> | |
</div> | |
<input type="hidden" name="saveedit" value="<?php echo $_REQUEST['edit']; | |
?>"/> | |
<input type="submit" value="Save"/> | |
</div></form> | |
<?php | |
if ($_REQUEST['edit']) { | |
echo "Informed Entities for ID {$_REQUEST['edit']}:"; | |
echo '<table>'; | |
foreach(getInformedAlerts($_REQUEST['edit'], "", "") as $informed) { | |
echo "<tr><td>{$informed['informed_class']}</td><td>{$informed['informed_id']}</td><td>{$informed['informed_action']}" . '</td><td><a href="?delete=' . $_REQUEST['edit'] . ';' . $informed['informed_class'] . ';' . $informed['informed_id'] . '">delete</a></td></tr>'; | |
} | |
echo '</table>'; | |
?> | |
<form action="<?php echo basename(__FILE__) ; | |
?>" method="get"> | |
<input type="hidden" name="networkinform" value="<?php echo $_REQUEST['edit']; | |
?>"/> | |
<input type="submit" value="Add Network Inform"/> | |
</form> | |
<form action="<?php echo basename(__FILE__) ; | |
?>" method="get"> | |
<div data-role="fieldcontain"> | |
<label for="stopid">StopID</label> | |
<input type="text" name="stopid" /> | |
</div> | |
<input type="hidden" name="stopsearch" value="<?php echo $_REQUEST['edit']; | |
?>"/> | |
<input type="submit" value="Stop Search"/> | |
</form> | |
<form action="<?php echo basename(__FILE__) ; | |
?>" method="get"> | |
<div data-role="fieldcontain"> | |
<label for="street">Street</label> | |
<input type="text" name="street" /> | |
</div> | |
<input type="hidden" name="streetsearch" value="<?php echo $_REQUEST['edit']; | |
?>"/> | |
<input type="submit" value="Street Search"/> | |
</form> | |
<form action="<?php echo basename(__FILE__) ; | |
?>" method="get"> | |
<div data-role="fieldcontain"> | |
<label for="routeid">routeID</label> | |
<input type="text" name="routeid" /> | |
</div> | |
<input type="hidden" name="routesearch" value="<?php echo $_REQUEST['edit']; | |
?>"/> | |
<input type="submit" value="Route Search"/> | |
</form> | |
<?php | |
} | |
include_footer(); | |
?> |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
$stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); | $stopid = filter_var($_REQUEST['stopid'], FILTER_SANITIZE_NUMBER_INT); |
$url = $APIurl . "/json/stop?stop_id=" . $stopid; | $url = $APIurl . "/json/stop?stop_id=" . $stopid; |
$stop = json_decode(getPage($url)); | $stop = json_decode(getPage($url)); |
$html.= '<table><tr><td><br><br> '; | $html.= '<table><tr><td><br><br> '; |
$url = $APIurl . "/json/stoproutes?stop=" . $stopid . "&time=" . midnight_seconds() . "&service_period=" . service_period(); | $url = $APIurl . "/json/stoproutes?stop=" . $stopid . "&time=" . midnight_seconds() . "&service_period=" . service_period(); |
$routes = json_decode(getPage($url)); | $routes = json_decode(getPage($url)); |
foreach ($routes as $route) { | foreach ($routes as $route) { |
$html.= '<br> <a href="trip.php?routeid=' . $route[0] . '&stopid=' . $stopid . '">' . $route[1] . ' - ' . $route[2] . '</a>'; | $html.= '<br> <a href="trip.php?routeid=' . $route[0] . '&stopid=' . $stopid . '">' . $route[1] . ' - ' . $route[2] . '</a>'; |
$viaPoints = viaPointNames($route[3], $stopid); | $viaPoints = viaPointNames($route[3], $stopid); |
if ($viaPoints != "") $html.= '<br><small>Via: ' . $viaPoints . '</small>'; | if ($viaPoints != "") |
$html.= "<br>"; | $html.= '<br><small>Via: ' . $viaPoints . '</small>'; |
$html.= "<br>"; | |
} | } |
$html.= '</td><td>' . staticmap(Array( | $html.= '</td><td>' . staticmap(Array( |
0 => Array( | 0 => Array( |
$stop[2], | $stop[2], |
$stop[3] | $stop[3] |
) | ) |
) , 0, "iconb", false) . "</td></tr>"; | ), 0, false) . "</td></tr>"; |
$url = $APIurl . "/json/stoptrips?stop=" . $stopid . "&time=" . midnight_seconds() . "&service_period=" . service_period(); | $url = $APIurl . "/json/stoptrips?stop=" . $stopid . "&time=" . midnight_seconds() . "&service_period=" . service_period(); |
$trips = json_decode(getPage($url)); | $trips = json_decode(getPage($url)); |
$html.= "</table><br><br><table>"; | $html.= "</table><br><br><table>"; |
$html.= "<thead><tr><th>Route</th><th>Time</th></tr></thead>"; | $html.= "<thead><tr><th>Route</th><th>Time</th></tr></thead>"; |
debug(print_r($trips, true)); | debug(print_r($trips, true)); |
foreach ($trips as $row) { | foreach ($trips as $row) { |
$html.= '<tr><td><a href="trip.php?stopid=' . $stopid . '&tripid=' . $row[1][0] . '">' . $row[1][1] . "</a></td>"; | $html.= '<tr><td><a href="trip.php?stopid=' . $stopid . '&tripid=' . $row[1][0] . '">' . $row[1][1] . "</a></td>"; |
$html.= '<td>' . midnight_seconds_to_time($row[0]) . '</td>'; | $html.= '<td>' . midnight_seconds_to_time($row[0]) . '</td>'; |
$html.= '</tr>'; | $html.= '</tr>'; |
} | } |
$html.= '</table>'; | $html.= '</table>'; |
if (sizeof($trips) == 0) $html.= "<center>No trips in the near future.</center>"; | if (sizeof($trips) == 0) |
$html.= "<center>No trips in the near future.</center>"; | |
require_once ('lib/tcpdf/config/lang/eng.php'); | require_once ('lib/tcpdf/config/lang/eng.php'); |
require_once ('lib/tcpdf/tcpdf.php'); | require_once ('lib/tcpdf/tcpdf.php'); |
// create new PDF document | // create new PDF document |
class Custom_TCPDF extends TCPDF | class Custom_TCPDF extends TCPDF { |
{ | |
var $QRCodeURL; | var $QRCodeURL; |
function set_QRCodeURL($url) | |
{ | function set_QRCodeURL($url) { |
$this->QRCodeURL = $url; | $this->QRCodeURL = $url; |
} | } |
/** | |
* This method is used to render the page header. | /** |
* It is automatically called by AddPage() and could be overwritten in your own inherited class. | * This method is used to render the page header. |
* @public | * It is automatically called by AddPage() and could be overwritten in your own inherited class. |
*/ | * @public |
public function Header() | */ |
{ | public function Header() { |
if ($this->header_xobjid < 0) { | if ($this->header_xobjid < 0) { |
// start a new XObject Template | // start a new XObject Template |
$this->header_xobjid = $this->startTemplate($this->w, $this->tMargin + 10); | $this->header_xobjid = $this->startTemplate($this->w, $this->tMargin + 10); |
$headerfont = $this->getHeaderFont(); | $headerfont = $this->getHeaderFont(); |
$headerdata = $this->getHeaderData(); | $headerdata = $this->getHeaderData(); |
$this->y = $this->header_margin; | $this->y = $this->header_margin; |
if ($this->rtl) { | if ($this->rtl) { |
$this->x = $this->w - $this->original_rMargin; | $this->x = $this->w - $this->original_rMargin; |
} | } else { |
else { | $this->x = $this->original_lMargin - 10; |
$this->x = $this->original_lMargin - 10; | } |
} | if (isset($this->QRCodeURL)) { |
if (isset($this->QRCodeURL)) { | // QRCODE,H : QR-CODE Best error correction |
// QRCODE,H : QR-CODE Best error correction | $style = array( |
$style = array( | 'border' => 1, |
'border' => 1, | 'padding' => 0, |
'padding' => 0, | 'fgcolor' => array( |
'fgcolor' => array( | 0, |
0, | 0, |
0, | 0 |
0 | ), |
) , | 'bgcolor' => false, //array(255,255,255) |
'bgcolor' => false, //array(255,255,255) | 'module_width' => 1, // width of a single module in points |
'module_width' => 1, // width of a single module in points | 'module_height' => 1 |
'module_height' => 1 | // height of a single module in points |
// height of a single module in points | ); |
$this->write2DBarcode($this->QRCodeURL, 'QRCODE,H', '', '', 25, 25, $style, 'T'); | |
); | $imgy = 50 + 20; |
$this->write2DBarcode($this->QRCodeURL, 'QRCODE,H', '', '', 25, 25, $style, 'T'); | } elseif (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) { |
$imgy = 50 + 20; | $imgtype = $this->getImageFileType(K_PATH_IMAGES . $headerdata['logo']); |
} | if (($imgtype == 'eps') OR ($imgtype == 'ai')) { |
elseif (($headerdata['logo']) AND ($headerdata['logo'] != K_BLANK_IMAGE)) { | $this->ImageEps(K_PATH_IMAGES . $headerdata['logo'], '', '', $headerdata['logo_width']); |
$imgtype = $this->getImageFileType(K_PATH_IMAGES . $headerdata['logo']); | } elseif ($imgtype == 'svg') { |
if (($imgtype == 'eps') OR ($imgtype == 'ai')) { | $this->ImageSVG(K_PATH_IMAGES . $headerdata['logo'], '', '', $headerdata['logo_width']); |
$this->ImageEps(K_PATH_IMAGES . $headerdata['logo'], '', '', $headerdata['logo_width']); | } else { |
} | $this->Image(K_PATH_IMAGES . $headerdata['logo'], '', '', $headerdata['logo_width']); |
elseif ($imgtype == 'svg') { | } |
$this->ImageSVG(K_PATH_IMAGES . $headerdata['logo'], '', '', $headerdata['logo_width']); | $imgy = $this->getImageRBY(); |
} | } else { |
else { | $imgy = $this->y; |
$this->Image(K_PATH_IMAGES . $headerdata['logo'], '', '', $headerdata['logo_width']); | } |
} | $cell_height = round(($this->cell_height_ratio * $headerfont[2]) / $this->k, 2); |
$imgy = $this->getImageRBY(); | // set starting margin for text data cell |
} | if ($this->getRTL()) { |
else { | $header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1); |
$imgy = $this->y; | } else { |
} | $header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1); |
$cell_height = round(($this->cell_height_ratio * $headerfont[2]) / $this->k, 2); | } |
// set starting margin for text data cell | $cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1); |
if ($this->getRTL()) { | $this->SetTextColor(0, 0, 0); |
$header_x = $this->original_rMargin + ($headerdata['logo_width'] * 1.1); | // header title |
} | $this->SetFont($headerfont[0], 'B', $headerfont[2] + 1); |
else { | $this->SetX($header_x); |
$header_x = $this->original_lMargin + ($headerdata['logo_width'] * 1.1); | $this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0); |
} | // header string |
$cw = $this->w - $this->original_lMargin - $this->original_rMargin - ($headerdata['logo_width'] * 1.1); | $this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]); |
$this->SetTextColor(0, 0, 0); | $this->SetX($header_x); |
// header title | $this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false); |
$this->SetFont($headerfont[0], 'B', $headerfont[2] + 1); | // print an ending header line |
$this->SetX($header_x); | //$this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))); |
$this->Cell($cw, $cell_height, $headerdata['title'], 0, 1, '', 0, '', 0); | //$this->SetY((2.835 / $this->k) + max($imgy, $this->y)); |
// header string | if ($this->rtl) { |
$this->SetFont($headerfont[0], $headerfont[1], $headerfont[2]); | $this->SetX($this->original_rMargin); |
$this->SetX($header_x); | } else { |
$this->MultiCell($cw, $cell_height, $headerdata['string'], 0, '', 0, 1, '', '', true, 0, false); | $this->SetX($this->original_lMargin); |
// print an ending header line | } |
//$this->SetLineStyle(array('width' => 0.85 / $this->k, 'cap' => 'butt', 'join' => 'miter', 'dash' => 0, 'color' => array(0, 0, 0))); | //$this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C'); |
//$this->SetY((2.835 / $this->k) + max($imgy, $this->y)); | $this->endTemplate(); |
if ($this->rtl) { | } |
$this->SetX($this->original_rMargin); | // print header template |
} | $x = 0; |
else { | $dx = 0; |
$this->SetX($this->original_lMargin); | if ($this->booklet AND (($this->page % 2) == 0)) { |
} | // adjust margins for booklet mode |
//$this->Cell(($this->w - $this->original_lMargin - $this->original_rMargin), 0, '', 'T', 0, 'C'); | $dx = ($this->original_lMargin - $this->original_rMargin); |
$this->endTemplate(); | } |
} | if ($this->rtl) { |
// print header template | $x = $this->w + $dx; |
$x = 0; | } else { |
$dx = 0; | $x = 0 + $dx; |
if ($this->booklet AND (($this->page % 2) == 0)) { | } |
// adjust margins for booklet mode | $this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false); |
$dx = ($this->original_lMargin - $this->original_rMargin); | } |
} | |
if ($this->rtl) { | |
$x = $this->w + $dx; | |
} | |
else { | |
$x = 0 + $dx; | |
} | |
$this->printTemplate($this->header_xobjid, $x, 0, 0, 0, '', '', false); | |
} | |
} | } |
$pdf = new Custom_TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); | $pdf = new Custom_TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); |
// set document information | // set document information |
$pdf->SetCreator(PDF_CREATOR); | $pdf->SetCreator(PDF_CREATOR); |
$pdf->SetAuthor('bus.lambdacomplex.org'); | $pdf->SetAuthor('bus.lambdacomplex.org'); |
$pdf->SetTitle($stop[1]); | $pdf->SetTitle($stop[1]); |
// set default header data | // set default header data |
$pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, $stop[1] . " Timetable", "Some description of customization like Weekdays, 9am-10am"); | $pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, $stop[1] . " Timetable", "Some description of customization like Weekdays, 9am-10am"); |
$pdf->set_QRCodeURL(curPageURL() . "stop.php?stopid=" . $_REQUEST['stopid']); | $pdf->set_QRCodeURL(curPageURL() . "stop.php?stopid=" . $_REQUEST['stopid']); |
// set header and footer fonts | // set header and footer fonts |
$pdf->setHeaderFont(Array( | $pdf->setHeaderFont(Array( |
PDF_FONT_NAME_MAIN, | PDF_FONT_NAME_MAIN, |
'', | '', |
PDF_FONT_SIZE_MAIN | PDF_FONT_SIZE_MAIN |
)); | )); |
$pdf->setFooterFont(Array( | $pdf->setFooterFont(Array( |
PDF_FONT_NAME_DATA, | PDF_FONT_NAME_DATA, |
'', | '', |
PDF_FONT_SIZE_DATA | PDF_FONT_SIZE_DATA |
)); | )); |
// set default monospaced font | // set default monospaced font |
$pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); | $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED); |
//set margins | //set margins |
$pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); | $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); |
$pdf->SetHeaderMargin(PDF_MARGIN_HEADER); | $pdf->SetHeaderMargin(PDF_MARGIN_HEADER); |
$pdf->SetFooterMargin(PDF_MARGIN_FOOTER); | $pdf->SetFooterMargin(PDF_MARGIN_FOOTER); |
//set auto page breaks | //set auto page breaks |
$pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); | $pdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM); |
//set image scale factor | //set image scale factor |
$pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); | $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO); |
//set some language-dependent strings | //set some language-dependent strings |
$pdf->setLanguageArray($l); | $pdf->setLanguageArray($l); |
// --------------------------------------------------------- | // --------------------------------------------------------- |
// set default font subsetting mode | // set default font subsetting mode |
$pdf->setFontSubsetting(true); | $pdf->setFontSubsetting(true); |
// Set font | // Set font |
// dejavusans is a UTF-8 Unicode font, if you only need to | // dejavusans is a UTF-8 Unicode font, if you only need to |
// print standard ASCII chars, you can use core fonts like | // print standard ASCII chars, you can use core fonts like |
// helvetica or times to reduce file size. | // helvetica or times to reduce file size. |
$pdf->SetFont('helvetica', '', 14, '', true); | $pdf->SetFont('helvetica', '', 14, '', true); |
// Add a page | // Add a page |
// This method has several options, check the source code documentation for more information. | // This method has several options, check the source code documentation for more information. |
$pdf->AddPage(); | $pdf->AddPage(); |
// Print text using writeHTMLCell() | // Print text using writeHTMLCell() |
$pdf->writeHTMLCell($w = 0, $h = 0, $x = '', $y = '', $html, $border = 0, $ln = 1, $fill = 0, $reseth = true, $align = '', $autopadding = true); | $pdf->writeHTMLCell($w = 0, $h = 0, $x = '', $y = '', $html, $border = 0, $ln = 1, $fill = 0, $reseth = true, $align = '', $autopadding = true); |
// --------------------------------------------------------- | // --------------------------------------------------------- |
// Close and output PDF document | // Close and output PDF document |
// This method has several options, check the source code documentation for more information. | // This method has several options, check the source code documentation for more information. |
$pdf->Output('example_001.pdf', 'I'); | $pdf->Output('example_001.pdf', 'I'); |
//============================================================+ | //============================================================+ |
// END OF FILE | // END OF FILE |
//============================================================+ | //============================================================+ |
?> | ?> |
<?php | <?php |
header('Content-type: application/vnd.google-earth.kml+xml'); | |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
header('Content-type: application/vnd.google-earth.kml+xml'); | |
//http://wiki.openstreetmap.org/wiki/OpenLayers_Dynamic_KML | //http://wiki.openstreetmap.org/wiki/OpenLayers_Dynamic_KML |
// Creates the KML/XML Document. | |
$dom = new DOMDocument('1.0', 'UTF-8'); | |
// Creates the KML/XML Document. | // Creates the root KML element and appends it to the root document. |
$dom = new DOMDocument('1.0', 'UTF-8'); | $node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml'); |
$parNode = $dom->appendChild($node); | |
// Creates the root KML element and appends it to the root document. | |
$node = $dom->createElementNS('http://earth.google.com/kml/2.1', 'kml'); | // Creates a KML Document element and append it to the KML element. |
$parNode = $dom->appendChild($node); | $dnode = $dom->createElement('Document'); |
$docNode = $parNode->appendChild($dnode); | |
// Creates a KML Document element and append it to the KML element. | |
$dnode = $dom->createElement('Document'); | |
$docNode = $parNode->appendChild($dnode); | |
$bbox = $_GET['bbox']; // get the bbox param from google earth | $bbox = $_GET['bbox']; // get the bbox param from google earth |
list($bbox_south, $bbox_west, $bbox_north,$bbox_east) = explode(",", $bbox); // west, south, east, north | list($bbox_south, $bbox_west, $bbox_north, $bbox_east) = explode(",", $bbox); // west, south, east, north |
include ('../include/common.inc.php'); | include ('../include/common.inc.php'); |
$debugOkay = Array(); | $debugOkay = Array(); |
$contents = getNearbyStops( (($bbox_west+ $bbox_east) /2), ($bbox_south + $bbox_north)/2 ,50, 3000); | $contents = getNearbyStops((($bbox_west + $bbox_east) / 2), ($bbox_south + $bbox_north) / 2, 50, 3000); |
foreach ($contents as $stop) { | foreach ($contents as $stop) { |
$description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] ." <br>"; | $description = 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] . " <br>"; |
$trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3); | $trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3); |
if ($trips) { | if ($trips) { |
foreach ($trips as $key => $row) { | foreach ($trips as $key => $row) { |
if ($key < 3) { | if ($key < 3) { |
$description .= $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time'] . "<br>"; | $description .= $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time'] . "<br>"; |
} | } |
} | } |
} else { | } else { |
$description .= "No more trips today"; | $description .= "No more trips today"; |
} | } |
// Creates a Placemark and append it to the Document. | // Creates a Placemark and append it to the Document. |
$node = $dom->createElement('Placemark'); | $node = $dom->createElement('Placemark'); |
$placeNode = $docNode->appendChild($node); | $placeNode = $docNode->appendChild($node); |
// Creates an id attribute and assign it the value of id column. | // Creates an id attribute and assign it the value of id column. |
$placeNode->setAttribute('id', 'placemark' . $stop['stop_id']); | $placeNode->setAttribute('id', 'placemark' . $stop['stop_id']); |
// Create name, and description elements and assigns them the values of the name and address columns from the results. | // Create name, and description elements and assigns them the values of the name and address columns from the results. |
$nameNode = $dom->createElement('name',htmlentities($stop['stop_name'])); | $nameNode = $dom->createElement('name', htmlentities($stop['stop_name'])); |
$descriptionNode = $dom->createElement('description',$description); | $descriptionNode = $dom->createElement('description', $description); |
$placeNode->appendChild($nameNode); | $placeNode->appendChild($nameNode); |
$placeNode->appendChild($descriptionNode); | $placeNode->appendChild($descriptionNode); |
// Creates a Point element. | // Creates a Point element. |
$pointNode = $dom->createElement('Point'); | $pointNode = $dom->createElement('Point'); |
$placeNode->appendChild($pointNode); | $placeNode->appendChild($pointNode); |
// Creates a coordinates element and gives it the value of the lng and lat columns from the results. | // Creates a coordinates element and gives it the value of the lng and lat columns from the results. |
$coorStr = $stop['stop_lon'] . ',' . $stop['stop_lat']; | $coorStr = $stop['stop_lon'] . ',' . $stop['stop_lat']; |
$coorNode = $dom->createElement('coordinates', $coorStr); | $coorNode = $dom->createElement('coordinates', $coorStr); |
$pointNode->appendChild($coorNode); | $pointNode->appendChild($coorNode); |
} | } |
$kmlOutput = $dom->saveXML(); | $kmlOutput = $dom->saveXML(); |
echo $kmlOutput; | echo $kmlOutput; |
?> | ?> |
<html xmlns="http://www.w3.org/1999/xhtml"> | <html xmlns="http://www.w3.org/1999/xhtml"> |
<head> | <!-- |
<script src="openlayers/OpenLayers.js"></script> | /* |
<SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT> | * Copyright 2010,2011 Alexander Sadleir |
<script type="text/javascript"> | |
var map,select; | Licensed under the Apache License, Version 2.0 (the "License"); |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
--> | |
<head> | |
<script src="openlayers/OpenLayers.js"></script> | |
<SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT> | |
<script type="text/javascript"> | |
var map,select; | |
function init() | function init() |
{ | { |
var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15); | var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15); |
// set up the map options | // set up the map options |
var options = | var options = |
{ | { |
maxExtent: extent, | maxExtent: extent, |
numZoomLevels: 20, | numZoomLevels: 20, |
}; | }; |
// create the ol map object | // create the ol map object |
map = new OpenLayers.Map('map', options); | map = new OpenLayers.Map('map', options); |
var osmtiles = new OpenLayers.Layer.OSM("OSM"); | var osmtiles = new OpenLayers.Layer.OSM("OSM"); |
var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap"); | var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap"); |
var stopbrowser = new OpenLayers.Layer.Vector("POI", { | var stopbrowser = new OpenLayers.Layer.Vector("POI", { |
projection: new OpenLayers.Projection("EPSG:4326"), | projection: new OpenLayers.Projection("EPSG:4326"), |
strategies: [ | strategies: [ |
new OpenLayers.Strategy.BBOX(), | new OpenLayers.Strategy.BBOX(), |
], | ], |
protocol: new OpenLayers.Protocol.HTTP({ | protocol: new OpenLayers.Protocol.HTTP({ |
url: "stopBrowser.kml.php", //Note that it is probably worth adding a Math.random() on the end of the URL to stop caching. | url: "stopBrowser.kml.php", //Note that it is probably worth adding a Math.random() on the end of the URL to stop caching. |
format: new OpenLayers.Format.KML({ | format: new OpenLayers.Format.KML({ |
extractStyles: true, | extractStyles: true, |
extractAttributes: true | extractAttributes: true |
}), | }), |
}) | }) |
}); | }); |
map.addLayers([osmtiles,stopbrowser,nearmap]); | map.addLayers([osmtiles,stopbrowser,nearmap]); |
var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()); | var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()); |
map.setCenter(lonLat, 15); | map.setCenter(lonLat, 15); |
map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false})); | map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false})); |
map.addControl(new OpenLayers.Control.MousePosition( | map.addControl(new OpenLayers.Control.MousePosition( |
{ | { |
displayProjection: new OpenLayers.Projection("EPSG:4326"), | displayProjection: new OpenLayers.Projection("EPSG:4326"), |
suffix: "__________________________________" | suffix: "__________________________________" |
})); | })); |
map.addControl(new OpenLayers.Control.MousePosition( | map.addControl(new OpenLayers.Control.MousePosition( |
{ | { |
displayProjection: new OpenLayers.Projection("EPSG:900913") | displayProjection: new OpenLayers.Projection("EPSG:900913") |
})); | })); |
select = new OpenLayers.Control.SelectFeature(stopbrowser); | select = new OpenLayers.Control.SelectFeature(stopbrowser); |
stopbrowser.events.on({ | stopbrowser.events.on({ |
"featureselected": onFeatureSelect, | "featureselected": onFeatureSelect, |
"featureunselected": onFeatureUnselect | "featureunselected": onFeatureUnselect |
}); | }); |
map.addControl(select); | map.addControl(select); |
select.activate(); | select.activate(); |
} | |
function onPopupClose(evt) { | |
select.unselectAll(); | |
} | |
function onFeatureSelect(event) { | |
var feature = event.feature; | |
// Since KML is user-generated, do naive protection against | |
// Javascript. | |
var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description; | |
if (content.search("<script") != -1) { | |
content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "<"); | |
} | } |
popup = new OpenLayers.Popup.FramedCloud("chicken", | function onPopupClose(evt) { |
feature.geometry.getBounds().getCenterLonLat(), | select.unselectAll(); |
new OpenLayers.Size(100,100), | |
content, | |
null, true, onPopupClose); | |
feature.popup = popup; | |
map.addPopup(popup); | |
} | |
function onFeatureUnselect(event) { | |
var feature = event.feature; | |
if(feature.popup) { | |
map.removePopup(feature.popup); | |
feature.popup.destroy(); | |
delete feature.popup; | |
} | } |
} | function onFeatureSelect(event) { |
</script> | var feature = event.feature; |
// Since KML is user-generated, do naive protection against | |
// Javascript. | |
var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description; | |
if (content.search("<script") != -1) { | |
content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "<"); | |
} | |
popup = new OpenLayers.Popup.FramedCloud("chicken", | |
feature.geometry.getBounds().getCenterLonLat(), | |
new OpenLayers.Size(100,100), | |
content, | |
null, true, onPopupClose); | |
feature.popup = popup; | |
map.addPopup(popup); | |
} | |
function onFeatureUnselect(event) { | |
var feature = event.feature; | |
if(feature.popup) { | |
map.removePopup(feature.popup); | |
feature.popup.destroy(); | |
delete feature.popup; | |
} | |
} | |
</script> | |
</head> | </head> |
<body onload="init()"> | <body onload="init()"> |
<div id="map" width="100%" height="100%" class="smallmap"></div> | <div id="map" width="100%" height="100%" class="smallmap"></div> |
</body> | </body> |
</html> | </html> |
<?php | |
include ('../include/common.inc.php'); | |
$query = "Select route_short_name,max(route_id) as route_id from routes where route_short_name NOT LIKE '7__' AND route_short_name != '170' AND route_short_name NOT LIKE '9__' group by route_short_name order by route_short_name ;"; | |
debug($query, "database"); | |
$query = $conn->prepare($query); | |
$query->execute(); | |
echo "<table><tr><th>Route Number</th><th>First Trip Start</th><th>First Trip End</th><th>Length</th>"; | |
$total = 0; | |
$count = 0; | |
foreach($query->fetchAll() as $r) { | |
$trips = getRouteTrips($r['route_id']); | |
$startTime = $trips[0]['arrival_time']; | |
$endTime = getTripEndTime($trips[0]['trip_id']); | |
$timeDiff = strtotime($endTime) - strtotime($startTime); | |
$total += $timeDiff; | |
$count ++; | |
echo "<tr><td>{$r['route_short_name']}</td><td>$startTime</td><td>$endTime</td><td>$timeDiff seconds ie. ". ($timeDiff/60). " minutes</td></tr>"; | |
} | |
echo "</table>"; | |
echo "Total time: $total seconds ie. " .($total/60/60). " hours<br>"; | |
echo "$count Routes"; | |
?> |
<?php | |
// http://www.herethere.net/~samson/php/color_gradient/color_gradient_generator.php.txt | |
// return the interpolated value between pBegin and pEnd | |
function interpolate($pBegin, $pEnd, $pStep, $pMax) | |
{ | |
if ($pBegin < $pEnd) { | |
return (($pEnd - $pBegin) * ($pStep / $pMax)) + $pBegin; | |
} | |
else { | |
return (($pBegin - $pEnd) * (1 - ($pStep / $pMax))) + $pEnd; | |
} | |
} | |
require ("../lib/rolling-curl/RollingCurl.php"); | |
function processResult_cb($response, $info, $request) | |
{ | |
global $testRegions, $regionTimes,$csv,$kml, $latdeltasize,$londeltasize; | |
$md = $request->metadata; | |
$tripplan = json_decode($response); | |
$plans = Array(); | |
//var_dump(Array($info, $request)); | |
if (is_array($tripplan->plan->itineraries->itinerary)) { | |
foreach ($tripplan->plan->itineraries->itinerary as $itineraryNumber => $itinerary) { | |
$plans[floor($itinerary->duration / 60000) ] = $itinerary; | |
} | |
} | |
else { | |
$plans[floor($tripplan->plan->itineraries->itinerary->duration / 60000) ] = $tripplan->plan->itineraries->itinerary; | |
} | |
if ($csv) echo "{$md['i']},{$md['j']}," . min(array_keys($plans)) . ",$latdeltasize, $londeltasize,{$md['key']}\n"; | |
if ($kml) { | |
$time = min(array_keys($plans)); | |
$plan = ""; | |
if (is_array($plans[min(array_keys($plans)) ]->legs->leg)) { | |
foreach ($plans[min(array_keys($plans)) ]->legs->leg as $legNumber => $leg) { | |
$plan.= processLeg($legNumber, $leg) . ","; | |
} | |
} | |
else { | |
$plan.= processLeg(0, $plans[min(array_keys($plans)) ]->legs->leg); | |
} | |
if (isset($tripplan->error) && $tripplan->error->id == 404) { | |
$time = 999; | |
$plan = "Trip not possible without excessive walking from nearest bus stop"; | |
} | |
$testRegions[] = Array( | |
"lat" => $md['i'], | |
"lon" => $md['j'], | |
"time" => $time, | |
"latdeltasize" => $latdeltasize, | |
"londeltasize" => $londeltasize, | |
"regionname" => $md['key'], | |
"plan" => $plan . '<br/><a href="' . htmlspecialchars($md['url']) . '">original plan</a>' | |
); | |
$regionTimes[] = $time; | |
} | |
} | |
function Gradient($HexFrom, $HexTo, $ColorSteps) | |
{ | |
$theColorBegin = hexdec($HexFrom); | |
$theColorEnd = hexdec($HexTo); | |
$theNumSteps = intval($ColorSteps); | |
$theR0 = ($theColorBegin & 0xff0000) >> 16; | |
$theG0 = ($theColorBegin & 0x00ff00) >> 8; | |
$theB0 = ($theColorBegin & 0x0000ff) >> 0; | |
$theR1 = ($theColorEnd & 0xff0000) >> 16; | |
$theG1 = ($theColorEnd & 0x00ff00) >> 8; | |
$theB1 = ($theColorEnd & 0x0000ff) >> 0; | |
$GradientColors = array(); | |
// generate gradient swathe now | |
for ($i = 0; $i <= $theNumSteps; $i++) { | |
$theR = interpolate($theR0, $theR1, $i, $theNumSteps); | |
$theG = interpolate($theG0, $theG1, $i, $theNumSteps); | |
$theB = interpolate($theB0, $theB1, $i, $theNumSteps); | |
$theVal = ((($theR << 8) | $theG) << 8) | $theB; | |
$GradientColors[] = sprintf("%06X", $theVal); | |
} | |
return $GradientColors; | |
} | |
function processLeg($legNumber, $leg) | |
{ | |
$legArray = object2array($leg); | |
if ($legArray["@mode"] === "BUS") { | |
return "bus {$legArray['@route']} " . str_replace("To", "towards", $legArray['@headsign']); | |
} | |
else { | |
return "walk"; | |
//$walkingstep = "walk "; | |
//if (strpos($step->streetName, "from") !== false && strpos($step->streetName, "way") !== false) { | |
// $walkingstep.= "footpath"; | |
//} | |
//else { | |
// $walkingstep.= $step->streetName; | |
//} | |
//$walkingstep.= floor($step->distance) . "m"; | |
//return $walkingstep; | |
} | |
} | |
$csv = false; | |
$kml = true; | |
$gearthcolors = false; | |
if ($kml) { | |
header('Content-Type: application/vnd.google-earth.kml+xml'); | |
echo '<?xml version="1.0" encoding="UTF-8"?> | |
<kml xmlns="http://www.opengis.net/kml/2.2"><Document>'; | |
} | |
include ('../include/common.inc.php'); | |
$boundingBoxes = Array( | |
"belconnen" => Array( | |
"startlat" => - 35.1928, | |
"startlon" => 149.006, | |
"finishlat" => - 35.2630, | |
"finishlon" => 149.1045, | |
) , | |
"north gungahlin civic" => Array( | |
"startlat" => - 35.1828, | |
"startlon" => 149.1045, | |
"finishlat" => - 35.2955, | |
"finishlon" => 149.1559, | |
) , | |
"west duffy" => Array( | |
"startlat" => - 35.3252, | |
"startlon" => 149.0240, | |
"finishlat" => - 35.3997, | |
"finishlon" => 149.0676, | |
) , | |
"central south" => Array( | |
"startlat" => - 35.3042, | |
"startlon" => 149.0762, | |
"finishlat" => - 35.3370, | |
"finishlon" => 149.1806, | |
) , | |
"south" => Array( | |
"startlat" => - 35.3403, | |
"startlon" => 149.0714, | |
"finishlat" => - 35.4607, | |
"finishlon" => 149.1243, | |
) | |
); | |
$latdeltasize = 0.005; | |
$londeltasize = 0.005; | |
$from = "Wattle Street"; | |
$fromPlace = (startsWith($from, "-") ? $from : geocode($from, false)); | |
$startTime = "9:00 am"; | |
$startDate = "03/21/2011"; // american dates, OTP does not validate! | |
$counter = 0; | |
$regionTimes = Array(); | |
$testRegions = Array(); | |
$useragent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.1) Gecko/20061204 Firefox/2.0.0.1"; | |
if ($kml) echo "<name> $from at $startTime on $startDate </name>"; | |
if ($csv) echo "<pre>"; | |
if ($csv) echo "lat,lon,time,latdeltasize, londeltasize, region key name\n"; | |
$rc = new RollingCurl("processResult_cb"); | |
$rc->window_size = 2; | |
foreach ($boundingBoxes as $key => $boundingBox) { | |
for ($i = $boundingBox['startlat']; $i >= $boundingBox['finishlat']; $i-= $latdeltasize) { | |
for ($j = $boundingBox['startlon']; $j <= $boundingBox['finishlon']; $j+= $londeltasize) { | |
$url = $otpAPIurl . "ws/plan?date=" . urlencode($startDate) . "&time=" . urlencode($startTime) . "&mode=TRANSIT%2CWALK&optimize=QUICK&maxWalkDistance=440&wheelchair=false&toPlace=" . $i . "," . $j . "&fromPlace=$fromPlace"; | |
//debug($url); | |
$request = new RollingCurlRequest($url); | |
$request->headers = Array( | |
"Accept: application/json" | |
); | |
$request->metadata = Array( "i" => $i, "j" => $j, "key" => $key, "url" => $url); | |
$rc->add($request); | |
} | |
} | |
} | |
$rc->execute(); | |
if ($kml) { | |
$colorSteps = 9; | |
//$minTime = min($regionTimes); | |
//$maxTime = max($regionTimes); | |
//$rangeTime = $maxTime - $minTime; | |
//$deltaTime = $rangeTime / $colorSteps; | |
$Gradients = Gradient(strrev("66FF00") , strrev("FF0000") , $colorSteps); // KML is BGR not RGB so strrev | |
foreach ($testRegions as $testRegion) { | |
//$band = (floor(($testRegion[time] - $minTime) / $deltaTime)); | |
$band = (floor($testRegion[time] / 10)); | |
if ($band > $colorSteps) $band = $colorSteps; | |
echo "<Placemark> | |
<name>" . $testRegion['regionname'] . " time {$testRegion['time']} band $band</name> | |
<description> <![CDATA[ {$testRegion['plan']} ]]> </description> | |
<Style> | |
<PolyStyle> | |
<color>c7" . $Gradients[$band] . "</color>" . // 7f = 50% alpha, c7=78% | |
"</PolyStyle> | |
<LineStyle> | |
<color>c7" . $Gradients[$band] . "</color>" . "</LineStyle> | |
</Style> | |
<Polygon> | |
<altitudeMode>relativeToGround</altitudeMode> | |
<outerBoundaryIs> | |
<LinearRing> | |
<coordinates> | |
" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] + ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] + ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] + ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] + ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . ($testRegion['lon'] - ($testRegion['londeltasize'] / 2)) . "," . ($testRegion['lat'] - ($testRegion['latdeltasize'] / 2)) . ",500\n" . " | |
</coordinates> | |
</LinearRing> | |
</outerBoundaryIs> | |
</Polygon> | |
</Placemark>"; | |
} | |
echo "\n</Document></kml>\n"; | |
} | |
if ($csv) echo "</pre>"; | |
?> | |
<html xmlns="http://www.w3.org/1999/xhtml"> | |
<head> | |
<script src="openlayers/OpenLayers.js"></script> | |
<SCRIPT TYPE="text/javascript" SRC="OpenStreetMap.js"></SCRIPT> | |
<script type="text/javascript"> | |
var map,select; | |
function init() | |
{ | |
var extent = new OpenLayers.Bounds(148.98, -35.48, 149.25, -35.15); | |
// set up the map options | |
var options = | |
{ | |
maxExtent: extent, | |
numZoomLevels: 20, | |
}; | |
// create the ol map object | |
map = new OpenLayers.Map('map', options); | |
var osmtiles = new OpenLayers.Layer.OSM("OSM"); | |
var nearmap = new OpenLayers.Layer.OSM.NearMap("NearMap"); | |
var tripplantest = new OpenLayers.Layer.GML("tripplantest", "tripPlannerTester.kml", { | |
format: OpenLayers.Format.KML, | |
formatOptions: { | |
extractStyles: true, | |
extractAttributes: true, | |
maxDepth: 2 | |
} | |
}); | |
map.addLayers([osmtiles,tripplantest,nearmap]); | |
var lonLat = new OpenLayers.LonLat(149.11, -35.28).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject()); | |
map.setCenter(lonLat, 11); | |
map.addControl( new OpenLayers.Control.LayerSwitcher({'ascending':false})); | |
map.addControl(new OpenLayers.Control.MousePosition( | |
{ | |
displayProjection: new OpenLayers.Projection("EPSG:4326"), | |
suffix: "__________________________________" | |
})); | |
map.addControl(new OpenLayers.Control.MousePosition( | |
{ | |
displayProjection: new OpenLayers.Projection("EPSG:900913") | |
})); | |
select = new OpenLayers.Control.SelectFeature(tripplantest); | |
tripplantest.events.on({ | |
"featureselected": onFeatureSelect, | |
"featureunselected": onFeatureUnselect | |
}); | |
map.addControl(select); | |
select.activate(); | |
} | |
function onPopupClose(evt) { | |
select.unselectAll(); | |
} | |
function onFeatureSelect(event) { | |
var feature = event.feature; | |
// Since KML is user-generated, do naive protection against | |
// Javascript. | |
var content = "<h2>"+feature.attributes.name + "</h2>" + feature.attributes.description; | |
if (content.search("<script") != -1) { | |
content = "Content contained Javascript! Escaped content below.<br />" + content.replace(/</g, "<"); | |
} | |
popup = new OpenLayers.Popup.FramedCloud("chicken", | |
feature.geometry.getBounds().getCenterLonLat(), | |
new OpenLayers.Size(100,100), | |
content, | |
null, true, onPopupClose); | |
feature.popup = popup; | |
map.addPopup(popup); | |
} | |
function onFeatureUnselect(event) { | |
var feature = event.feature; | |
if(feature.popup) { | |
map.removePopup(feature.popup); | |
feature.popup.destroy(); | |
delete feature.popup; | |
} | |
} | |
</script> | |
</head> | |
<body onload="init()"> | |
<div id="map" width="100%" height="100%" class="smallmap"></div> | |
</body> | |
</html> | |
<?php | <?php |
/* | |
* Copyright 2010,2011 Alexander Sadleir | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
*/ | |
include ('include/common.inc.php'); | include ('include/common.inc.php'); |
$output = Array(); | $output = Array(); |
$output['hotspots'] = Array(); | $output['hotspots'] = Array(); |
$output['layer'] = "canberrabusstops"; | $output['layer'] = "canberrabusstops"; |
$max_page = 10; | $max_page = 10; |
$max_results = 50; | $max_results = 50; |
$page_start = 0 + $pageKey; | $page_start = 0 + $pageKey; |
$page_end = $max_page + $pageKey; | $page_end = $max_page + $pageKey; |
$contents = getNearbyStops($lat, $lon, 50, $max_distance); | $contents = getNearbyStops($lat, $lon, 50, $max_distance); |
$stopNum = 0; | $stopNum = 0; |
foreach ($contents as $stop) { | foreach ($contents as $stop) { |
$stopNum++; | $stopNum++; |
if ($stopNum > $page_start && $stopNum <= $page_end) { | if ($stopNum > $page_start && $stopNum <= $page_end) { |
$hotspot = Array(); | $hotspot = Array(); |
$hotspot['id'] = $stop['stop_id']; | $hotspot['id'] = $stop['stop_id']; |
$hotspot['title'] = $stop['stop_name']; | $hotspot['title'] = $stop['stop_name']; |
$hotspot['type'] = 0; | $hotspot['type'] = 0; |
$hotspot['lat'] = floor($stop['stop_lat'] * 1000000); | $hotspot['lat'] = floor($stop['stop_lat'] * 1000000); |
$hotspot['lon'] = floor($stop['stop_lon'] * 1000000); | $hotspot['lon'] = floor($stop['stop_lon'] * 1000000); |
$hotspot['distance'] = floor($stop['distance']); | $hotspot['distance'] = floor($stop['distance']); |
$hotspot['attribution'] = "ACTION Buses"; | $hotspot['attribution'] = "ACTION Buses"; |
$hotspot['actions'] = Array( | $hotspot['actions'] = Array( |
Array( | Array( |
"label" => 'View more trips/information', | "label" => 'View more trips/information', |
'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] | 'uri' => 'http://bus.lambdacomplex.org/' . 'stop.php?stopid=' . $stop['stop_id'] |
) | ) |
); | ); |
$trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3); | $trips = getStopTripsWithTimes($stop['stop_id'], "", "", "", 3); |
foreach ($trips as $key => $row) { | foreach ($trips as $key => $row) { |
if ($key < 3) { | if ($key < 3) { |
$hotspot['line' . strval($key + 2) ] = $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time']; | $hotspot['line' . strval($key + 2)] = $row['route_short_name'] . ' ' . $row['route_long_name'] . ' @ ' . $row['arrival_time']; |
} | } |
} | } |
if (sizeof($trips) == 0) $hotspot['line2'] = 'No trips in the near future.'; | if (sizeof($trips) == 0) |
$output['hotspots'][] = $hotspot; | $hotspot['line2'] = 'No trips in the near future.'; |
} | $output['hotspots'][] = $hotspot; |
} | |
} | } |
if (sizeof($hotspot) > 0) { | if (sizeof($hotspot) > 0) { |
$output['errorString'] = 'ok'; | $output['errorString'] = 'ok'; |
$output['errorCode'] = 0; | $output['errorCode'] = 0; |
} else { | |
$output['errorString'] = 'no results, try increasing range'; | |
$output['errorCode'] = 21; | |
} | } |
else { | if ($page_end >= $max_results || sizeof($contents) < $page_start + $max_page) { |
$output['errorString'] = 'no results, try increasing range'; | $output["morePages"] = false; |
$output['errorCode'] = 21; | $output["nextPageKey"] = null; |
} | } else { |
if ($page_end >= $max_results || sizeof($contents) < $page_start+$max_page) { | $output["morePages"] = true; |
$output["morePages"] = false; | $output["nextPageKey"] = $page_end; |
$output["nextPageKey"] = null; | |
} | |
else { | |
$output["morePages"] = true; | |
$output["nextPageKey"] = $page_end; | |
} | } |
echo json_encode($output); | echo json_encode($output); |
?> | ?> |
The MIT License | |
Copyright (c) 2011 Iván -DrSlump- Montes | |
Permission is hereby granted, free of charge, to any person obtaining a copy | |
of this software and associated documentation files (the "Software"), to deal | |
in the Software without restriction, including without limitation the rights | |
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
copies of the Software, and to permit persons to whom the Software is | |
furnished to do so, subject to the following conditions: | |
The above copyright notice and this permission notice shall be included in | |
all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
THE SOFTWARE. |
Protobuf for PHP | |
================ | |
Protobuf for PHP is an implementation of Google's Protocol Buffers for the PHP | |
language, supporting its binary data serialization and including a `protoc` | |
plugin to generate PHP classes from .proto files. | |
Great effort has been put into generating PHP files that include all sort of type | |
hints to aide IDE's with autocompletion. Therefore, it can not only be used to | |
communicate with Protocol Buffers services but also as a generation tool for | |
_data objects_ no matter what the final serialization is. | |
For more information see the [included man pages](http://drslump.github.com/Protobuf-PHP/). | |
## Requirements | |
- PHP 5.3 | |
- Pear's Console_CommandLine (for the protoc wrapper tool) | |
- Google's `protoc` compiler version 2.3 or above | |
- GMP or BC Math extensions ¹ | |
¹ Only needed for negative values in `int32`, `int64` or `fixed64` types. See | |
the _known issues_ section. | |
## Features | |
### Working | |
- Standard types (numbers, string, enums, messages, etc) | |
- Pluggable serialization backends (codecs) | |
- Standard Binary | |
- Standard TextFormat ¹ | |
- PhpArray | |
- JSON | |
- [ProtoJson](https://github.com/drslump/ProtoJson) (_TagMap_ and _Indexed_ variants) | |
- XML | |
- Protoc compiler plugin to generate the PHP classes | |
- Extensions | |
- Unknown fields | |
- Packed fields | |
- Reflection | |
- Dynamic messages with annotations support | |
- Generates service interfaces | |
- Includes comments from .proto files in the generated files | |
- Pear package for easy installation | |
¹ Only serialization is supported | |
### Future | |
- Speed optimized code generation mode | |
- Support numbers beyond PHP's native limits | |
## Example usage | |
$person = new Tutorial\Person(); | |
$person->name = 'DrSlump'; | |
$person->setId(12); | |
$book = new Tutorial\AddressBook(); | |
$book->addPerson($person); | |
// Use default codec | |
$data = $book->serialize(); | |
// Use custom codec | |
$codec = new \DrSlump\Protobuf\Codec\Binary(); | |
$data = $codec->encode($book); | |
// ... or ... | |
$data = $book->serialize($codec); | |
## Installation | |
Install with Pear | |
pear channel-discover pear.pollinimini.net | |
pear install drslump/Protobuf-beta | |
You can also get the latest version by checking out a copy of the | |
repository in your computer. | |
## Known issues | |
### Types | |
PHP is very weak when dealing with numbers processing. Several work arounds have been applied | |
to the standard binary codec to reduce incompatibilities between Protobuf types and PHP ones. | |
- Protobuf stores floating point values using the [IEEE 754](http://en.wikipedia.org/wiki/IEEE_754) standard | |
with 64bit words for the `double` and 32bit for the `float` types. PHP supports IEEE 754 natively although | |
the precission is platform dependant, however it typically supports 64bit doubles. It means that | |
if your PHP was compiled with 64bit sized doubles (or greater) you shouldn't have any problem encoding | |
and decoded float and double typed values with Protobuf. | |
- Integer values are also [platform dependant in PHP](http://www.php.net/manual/en/language.types.integer.php). | |
The library has been developed and tested against PHP binaries compiled with 64bit integers. The encoding and | |
decoding algorithm should in theory work no matter if PHP uses 32bit or 64bit integers internally, just take | |
into account that with 32bit integers the numbers cannot exceed in any case the `PHP_INT_MAX` value (2147483647). | |
While Protobuf supports unsigned integers PHP does not. In fact, numbers above the compiled PHP maximum | |
integer (`PHP_INT_MAX`, 0x7FFFFFFFFFFFFFFF for 64bits) will be automatically casted to doubles, which | |
typically will offer 53bits of decimal precission, allowing to safely work with numbers upto | |
0x20000000000000 (2^53), even if they are represented in PHP as floats instead of integers. Higher numbers | |
will loose precission or might even return an _infinity_ value, note that the library does not include | |
any checking for these numbers and using them might provoke unexpected behaviour. | |
Negative values when encoded as `int32`, `int64` or `fixed64` types require the big integer extensions | |
[GMP](http://www.php.net/gmp) or [BC Math](http://www.php.net/bc) (the later only for 64bit architectures) | |
to be available in your PHP environment. The reason is that when encoding these negative numbers without | |
using _zigzag_ the binary representation uses the most significant bit for the sign, thus the numbers become | |
above the maximum supported values in PHP. The library will check for these conditions and will automatically | |
try to use GMP or BC to process the value. | |
### Strings | |
The binary codec expects strings to be encoded using UTF-8. PHP does not natively support string encodings, | |
PHP's string data type is basically a length delimited stream of bytes, so it's not trivial to include | |
automatic encoding conversion into the library encoding and decoding routines. Instead of trying to guess | |
or offer a configuration interface for the encoding, the binary codec will process the `string` type just as | |
it would process `byte` one, delegating on your application the task of encoding or decoding in the desired | |
character set. | |
### Memory usage | |
Large messages might be troublesome since the way the library is modelled does not allow to parse or | |
serialize messages as a streams, instead the whole operation is performed in memory, which allows for faster | |
processing but could consume too much RAM if messages are too large. | |
### Unknown fields | |
Since wire types are different across different codec's formats, it's not possible to transcode unkwnon | |
fields consumed in one codec to another. This means, for example, that when consuming a message using the | |
binary codec, if it contains unknown fields, they won't be included when serializing the message using the | |
Json codec. | |
## Generating PHP classes | |
The generation tool is designed to be run as a `protoc` plugin, thus it should | |
work with any proto file supported by the official compiler. | |
protoc --plugin=protoc-gen-php --php_out=./build tutorial.proto | |
To make use of non-standard options in your proto files (like `php.namespace`) you'll | |
have to import the `php.proto` file included with the library. It's location will | |
depend on where you've installed this library. | |
protoc -I=./Protobuf-PHP/library/DrSlump/Protobuf/Compiler/protos \ | |
--plugin=protoc-gen-php --php_out=./build tutorial.proto | |
In order to make your life easier, the supplied protoc plugin offers an additional | |
execution mode, where it acts as a wrapper for the `protoc` invocation. It will | |
automatically include the `php.proto` path so that you don't need to worry about it. | |
protoc-gen-php -o ./build tutorial.proto | |
## LICENSE: | |
The MIT License | |
Copyright (c) 2011 Iván -DrSlump- Montes | |
Permission is hereby granted, free of charge, to any person obtaining | |
a copy of this software and associated documentation files (the | |
'Software'), to deal in the Software without restriction, including | |
without limitation the rights to use, copy, modify, merge, publish, | |
distribute, sublicense, and/or sell copies of the Software, and to | |
permit persons to whom the Software is furnished to do so, subject to | |
the following conditions: | |
The above copyright notice and this permission notice shall be | |
included in all copies or substantial portions of the Software. | |
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | |
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | |
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | |
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
# encoding: utf-8 | |
namespace :pear do | |
support_files = ['README.md', 'LICENSE', 'protoc-gen-php.php', 'protoc-gen-php.bat'] | |
tpl_file = 'package.pear' | |
xml_file = 'library/package.xml' | |
desc "Generate package.xml" | |
task :xml => [:clean] do |t, args| | |
unless ENV['version'] then | |
puts 'Version number not given. Use "pear:xml version=1.0"' | |
exit 1 | |
end | |
# Get template contents | |
text = File.read(tpl_file, :encoding => "UTF-8") | |
# Replace the version, date and time | |
text = text.gsub("{VERSION}", ENV['version']) | |
text = text.gsub('{DATE}', Time.now.strftime('%Y-%m-%d')) | |
text = text.gsub('{TIME}', Time.now.strftime('%H:%M:%S')) | |
# Include source files | |
dirs = [] | |
Dir.glob('library/**/*.*') do |file| | |
file[0, 'library/'.length] = '' | |
dirs << '<file name="' + file + '" role="php">' | |
dirs << '<tasks:replace from="@package_version@" to="version" type="package-info" />' | |
dirs << '</file>' | |
end | |
text = text.gsub('{DIRS}', dirs.join("\n")) | |
# Generate a new pear package.xml | |
xml = File.new(xml_file, 'w') | |
xml.syswrite(text); | |
xml.close(); | |
end | |
desc "Build a release" | |
task :package => ['doc:build', :xml] do | |
# Copy supporting files to the package root | |
support_files.each do |file| | |
cp file, "library/#{file}" | |
end | |
begin | |
sh "pear package -n #{xml_file}" | |
rescue Exception => e | |
puts "Rolling back..." | |
Rake::Task['pear:clean'].execute | |
raise | |
end | |
Rake::Task['pear:clean'].execute | |
end | |
desc "Clean up" | |
task :clean do | |
puts "Cleaning up..." | |
# Remove package.xml | |
rm_f xml_file | |
# Remove supporting files | |
support_files.each { |file| rm_f "library/#{file}" } | |
end | |
end | |
namespace :doc do | |
desc "Generate manual" | |
task :build do | |
version = ENV['version'] | |
ENV['RONN_MANUAL'] = "Protobuf-PHP #{version}" | |
ENV['RONN_ORGANIZATION'] = "Ivan -DrSlump- Montes" | |
sh "ronn -w -s toc -r5 --markdown man/*.ronn" | |
end | |
desc 'Publish to github pages' | |
task :github => 'doc:build' do | |
require 'git' | |
require 'logger' | |
remote = `git remote show origin` | |
.split(%r{\n}) # Ruby 1.9 only has grep() on Array | |
.grep(/Push.*URL/) | |
.first[/git@.*/] | |
files = [ | |
'protoc-gen-php.1.html', | |
'protobuf-php.3.html', | |
'protobuf-php.5.html', | |
] | |
root = "/tmp/checkout-#{Time.now.to_i}" | |
g = Git.clone(remote, root, :log => Logger.new(STDOUT)) | |
# Make sure this actually switches branches. | |
g.checkout(g.branch('gh-pages')) | |
files.each {|file| | |
cp "man/#{file}", "#{root}/." | |
g.add(file) | |
} | |
g.commit('Regenerating Github Pages.') | |
# PUSH! | |
g.push(g.remote('origin'), g.branch('gh-pages')) | |
puts '--> GitHub Pages Commit and Push successful.' | |
end | |
end | |
<?php | |
// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin @package_version@ | |
// cmd line php -f protoc-gen-php.php gtfs-realtime.proto -i ./ | |
// Source: gtfs-realtime.proto | |
// Date: 2011-08-23 07:08:46 | |
// @@protoc_insertion_point(scope_file) | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class FeedMessage extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.FeedMessage'); | |
// required .transit_realtime.FeedHeader header = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "header"; | |
$f->type = 11; | |
$f->rule = 2; | |
$f->reference = '\transit_realtime\FeedHeader'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedMessage:header) | |
$descriptor->addField($f); | |
// repeated .transit_realtime.FeedEntity entity = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "entity"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\transit_realtime\FeedEntity'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedMessage:entity) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.FeedMessage) | |
return $descriptor; | |
} | |
/** @var \transit_realtime\FeedHeader */ | |
public $header = null; | |
/** @var \transit_realtime\FeedEntity[] */ | |
public $entity = array(); | |
/** | |
* Check if <header> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasHeader(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <header> value | |
* | |
* @return \transit_realtime\FeedMessage | |
*/ | |
public function clearHeader(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <header> value | |
* | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function getHeader(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <header> value | |
* | |
* @param \transit_realtime\FeedHeader $value | |
* @return \transit_realtime\FeedMessage | |
*/ | |
public function setHeader(\transit_realtime\FeedHeader $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <entity> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEntity(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <entity> value | |
* | |
* @return \transit_realtime\FeedMessage | |
*/ | |
public function clearEntity(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <entity> value | |
* | |
* @param int $idx | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function getEntity($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <entity> value | |
* | |
* @param \transit_realtime\FeedEntity $value | |
* @return \transit_realtime\FeedMessage | |
*/ | |
public function setEntity(\transit_realtime\FeedEntity $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <entity> | |
* | |
* @return \transit_realtime\FeedEntity[] | |
*/ | |
public function getEntityList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <entity> | |
* | |
* @param \transit_realtime\FeedEntity $value | |
* @return \transit_realtime\FeedMessage | |
*/ | |
public function addEntity(\transit_realtime\FeedEntity $value){ | |
return $this->_add(2, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.FeedMessage) | |
} | |
} | |
namespace transit_realtime\FeedHeader { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.FeedHeader) | |
class Incrementality { | |
const FULL_DATASET = 0; | |
const DIFFERENTIAL = 1; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.FeedHeader.Incrementality) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class FeedHeader extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.FeedHeader'); | |
// required gtfs_realtime_version = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "gtfs_realtime_version"; | |
$f->type = 9; | |
$f->rule = 2; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedHeader:gtfs_realtime_version) | |
$descriptor->addField($f); | |
// optional .transit_realtime.FeedHeader.Incrementality incrementality = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "incrementality"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\FeedHeader\Incrementality'; | |
$f->default = \transit_realtime\FeedHeader\Incrementality::FULL_DATASET; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedHeader:incrementality) | |
$descriptor->addField($f); | |
// optional timestamp = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "timestamp"; | |
$f->type = 4; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedHeader:timestamp) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.FeedHeader) | |
return $descriptor; | |
} | |
/** @var string */ | |
public $gtfs_realtime_version = null; | |
/** @var int - \transit_realtime\FeedHeader\Incrementality */ | |
public $incrementality = \transit_realtime\FeedHeader\Incrementality::FULL_DATASET; | |
/** @var int */ | |
public $timestamp = null; | |
/** | |
* Check if <gtfs_realtime_version> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasGtfsRealtimeVersion(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <gtfs_realtime_version> value | |
* | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function clearGtfsRealtimeVersion(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <gtfs_realtime_version> value | |
* | |
* @return string | |
*/ | |
public function getGtfsRealtimeVersion(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <gtfs_realtime_version> value | |
* | |
* @param string $value | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function setGtfsRealtimeVersion( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <incrementality> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasIncrementality(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <incrementality> value | |
* | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function clearIncrementality(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <incrementality> value | |
* | |
* @return int - \transit_realtime\FeedHeader\Incrementality | |
*/ | |
public function getIncrementality(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <incrementality> value | |
* | |
* @param int - \transit_realtime\FeedHeader\Incrementality $value | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function setIncrementality( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <timestamp> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTimestamp(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <timestamp> value | |
* | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function clearTimestamp(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <timestamp> value | |
* | |
* @return int | |
*/ | |
public function getTimestamp(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <timestamp> value | |
* | |
* @param int $value | |
* @return \transit_realtime\FeedHeader | |
*/ | |
public function setTimestamp( $value){ | |
return $this->_set(3, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.FeedHeader) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class FeedEntity extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.FeedEntity'); | |
// required id = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "id"; | |
$f->type = 9; | |
$f->rule = 2; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedEntity:id) | |
$descriptor->addField($f); | |
// optional is_deleted = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "is_deleted"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = false; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedEntity:is_deleted) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TripUpdate trip_update = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "trip_update"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripUpdate'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedEntity:trip_update) | |
$descriptor->addField($f); | |
// optional .transit_realtime.VehiclePosition vehicle = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "vehicle"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\VehiclePosition'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedEntity:vehicle) | |
$descriptor->addField($f); | |
// optional .transit_realtime.Alert alert = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "alert"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\Alert'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.FeedEntity:alert) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.FeedEntity) | |
return $descriptor; | |
} | |
/** @var string */ | |
public $id = null; | |
/** @var boolean */ | |
public $is_deleted = true; | |
/** @var \transit_realtime\TripUpdate */ | |
public $trip_update = null; | |
/** @var \transit_realtime\VehiclePosition */ | |
public $vehicle = null; | |
/** @var \transit_realtime\Alert */ | |
public $alert = null; | |
/** | |
* Check if <id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasId(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <id> value | |
* | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function clearId(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <id> value | |
* | |
* @return string | |
*/ | |
public function getId(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function setId( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <is_deleted> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasIsDeleted(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <is_deleted> value | |
* | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function clearIsDeleted(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <is_deleted> value | |
* | |
* @return boolean | |
*/ | |
public function getIsDeleted(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <is_deleted> value | |
* | |
* @param boolean $value | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function setIsDeleted( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <trip_update> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTripUpdate(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <trip_update> value | |
* | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function clearTripUpdate(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <trip_update> value | |
* | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function getTripUpdate(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <trip_update> value | |
* | |
* @param \transit_realtime\TripUpdate $value | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function setTripUpdate(\transit_realtime\TripUpdate $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <vehicle> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasVehicle(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <vehicle> value | |
* | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function clearVehicle(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <vehicle> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function getVehicle(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <vehicle> value | |
* | |
* @param \transit_realtime\VehiclePosition $value | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function setVehicle(\transit_realtime\VehiclePosition $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <alert> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasAlert(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <alert> value | |
* | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function clearAlert(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <alert> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function getAlert(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <alert> value | |
* | |
* @param \transit_realtime\Alert $value | |
* @return \transit_realtime\FeedEntity | |
*/ | |
public function setAlert(\transit_realtime\Alert $value){ | |
return $this->_set(5, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.FeedEntity) | |
} | |
} | |
namespace transit_realtime\TripUpdate { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.TripUpdate) | |
class StopTimeEvent extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripUpdate.StopTimeEvent'); | |
// optional delay = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "delay"; | |
$f->type = 5; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeEvent:delay) | |
$descriptor->addField($f); | |
// optional time = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "time"; | |
$f->type = 3; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeEvent:time) | |
$descriptor->addField($f); | |
// optional uncertainty = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "uncertainty"; | |
$f->type = 5; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeEvent:uncertainty) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TripUpdate.StopTimeEvent) | |
return $descriptor; | |
} | |
/** @var int */ | |
public $delay = null; | |
/** @var int */ | |
public $time = null; | |
/** @var int */ | |
public $uncertainty = null; | |
/** | |
* Check if <delay> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDelay(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <delay> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function clearDelay(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <delay> value | |
* | |
* @return int | |
*/ | |
public function getDelay(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <delay> value | |
* | |
* @param int $value | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function setDelay( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <time> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTime(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <time> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function clearTime(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <time> value | |
* | |
* @return int | |
*/ | |
public function getTime(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <time> value | |
* | |
* @param int $value | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function setTime( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <uncertainty> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUncertainty(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <uncertainty> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function clearUncertainty(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <uncertainty> value | |
* | |
* @return int | |
*/ | |
public function getUncertainty(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <uncertainty> value | |
* | |
* @param int $value | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function setUncertainty( $value){ | |
return $this->_set(3, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TripUpdate.StopTimeEvent) | |
} | |
} | |
namespace transit_realtime\TripUpdate\StopTimeUpdate { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.TripUpdate.StopTimeUpdate) | |
class ScheduleRelationship { | |
const SCHEDULED = 0; | |
const SKIPPED = 1; | |
const NO_DATA = 2; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TripUpdate.StopTimeUpdate.ScheduleRelationship) | |
} | |
} | |
namespace transit_realtime\TripUpdate { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.TripUpdate) | |
class StopTimeUpdate extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripUpdate.StopTimeUpdate'); | |
// optional stop_sequence = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "stop_sequence"; | |
$f->type = 13; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:stop_sequence) | |
$descriptor->addField($f); | |
// optional stop_id = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "stop_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:stop_id) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TripUpdate.StopTimeEvent arrival = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "arrival"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripUpdate\StopTimeEvent'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:arrival) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TripUpdate.StopTimeEvent departure = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "departure"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripUpdate\StopTimeEvent'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:departure) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TripUpdate.StopTimeUpdate.ScheduleRelationship schedule_relationship = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "schedule_relationship"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship'; | |
$f->default = \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SCHEDULED; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate.StopTimeUpdate:schedule_relationship) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TripUpdate.StopTimeUpdate) | |
return $descriptor; | |
} | |
/** @var int */ | |
public $stop_sequence = null; | |
/** @var string */ | |
public $stop_id = null; | |
/** @var \transit_realtime\TripUpdate\StopTimeEvent */ | |
public $arrival = null; | |
/** @var \transit_realtime\TripUpdate\StopTimeEvent */ | |
public $departure = null; | |
/** @var int - \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship */ | |
public $schedule_relationship = \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SCHEDULED; | |
/** | |
* Check if <stop_sequence> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStopSequence(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <stop_sequence> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function clearStopSequence(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <stop_sequence> value | |
* | |
* @return int | |
*/ | |
public function getStopSequence(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <stop_sequence> value | |
* | |
* @param int $value | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function setStopSequence( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <stop_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStopId(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <stop_id> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function clearStopId(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <stop_id> value | |
* | |
* @return string | |
*/ | |
public function getStopId(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <stop_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function setStopId( $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <arrival> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasArrival(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <arrival> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function clearArrival(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <arrival> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function getArrival(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <arrival> value | |
* | |
* @param \transit_realtime\TripUpdate\StopTimeEvent $value | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function setArrival(\transit_realtime\TripUpdate\StopTimeEvent $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <departure> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDeparture(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <departure> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function clearDeparture(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <departure> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeEvent | |
*/ | |
public function getDeparture(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <departure> value | |
* | |
* @param \transit_realtime\TripUpdate\StopTimeEvent $value | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function setDeparture(\transit_realtime\TripUpdate\StopTimeEvent $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <schedule_relationship> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasScheduleRelationship(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <schedule_relationship> value | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function clearScheduleRelationship(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <schedule_relationship> value | |
* | |
* @return int - \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship | |
*/ | |
public function getScheduleRelationship(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <schedule_relationship> value | |
* | |
* @param int - \transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship $value | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function setScheduleRelationship( $value){ | |
return $this->_set(5, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TripUpdate.StopTimeUpdate) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class TripUpdate extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripUpdate'); | |
// required .transit_realtime.TripDescriptor trip = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "trip"; | |
$f->type = 11; | |
$f->rule = 2; | |
$f->reference = '\transit_realtime\TripDescriptor'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate:trip) | |
$descriptor->addField($f); | |
// optional .transit_realtime.VehicleDescriptor vehicle = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "vehicle"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\VehicleDescriptor'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate:vehicle) | |
$descriptor->addField($f); | |
// repeated .transit_realtime.TripUpdate.StopTimeUpdate stop_time_update = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "stop_time_update"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\transit_realtime\TripUpdate\StopTimeUpdate'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripUpdate:stop_time_update) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TripUpdate) | |
return $descriptor; | |
} | |
/** @var \transit_realtime\TripDescriptor */ | |
public $trip = null; | |
/** @var \transit_realtime\VehicleDescriptor */ | |
public $vehicle = null; | |
/** @var \transit_realtime\TripUpdate\StopTimeUpdate[] */ | |
public $stop_time_update = array(); | |
/** | |
* Check if <trip> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTrip(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <trip> value | |
* | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function clearTrip(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <trip> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function getTrip(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <trip> value | |
* | |
* @param \transit_realtime\TripDescriptor $value | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function setTrip(\transit_realtime\TripDescriptor $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <vehicle> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasVehicle(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <vehicle> value | |
* | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function clearVehicle(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <vehicle> value | |
* | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function getVehicle(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <vehicle> value | |
* | |
* @param \transit_realtime\VehicleDescriptor $value | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function setVehicle(\transit_realtime\VehicleDescriptor $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <stop_time_update> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStopTimeUpdate(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <stop_time_update> value | |
* | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function clearStopTimeUpdate(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <stop_time_update> value | |
* | |
* @param int $idx | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate | |
*/ | |
public function getStopTimeUpdate($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <stop_time_update> value | |
* | |
* @param \transit_realtime\TripUpdate\StopTimeUpdate $value | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function setStopTimeUpdate(\transit_realtime\TripUpdate\StopTimeUpdate $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <stop_time_update> | |
* | |
* @return \transit_realtime\TripUpdate\StopTimeUpdate[] | |
*/ | |
public function getStopTimeUpdateList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <stop_time_update> | |
* | |
* @param \transit_realtime\TripUpdate\StopTimeUpdate $value | |
* @return \transit_realtime\TripUpdate | |
*/ | |
public function addStopTimeUpdate(\transit_realtime\TripUpdate\StopTimeUpdate $value){ | |
return $this->_add(2, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TripUpdate) | |
} | |
} | |
namespace transit_realtime\VehiclePosition { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.VehiclePosition) | |
class VehicleStopStatus { | |
const INCOMING_AT = 0; | |
const STOPPED_AT = 1; | |
const IN_TRANSIT_TO = 2; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.VehiclePosition.VehicleStopStatus) | |
} | |
} | |
namespace transit_realtime\VehiclePosition { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.VehiclePosition) | |
class CongestionLevel { | |
const UNKNOWN_CONGESTION_LEVEL = 0; | |
const RUNNING_SMOOTHLY = 1; | |
const STOP_AND_GO = 2; | |
const CONGESTION = 3; | |
const SEVERE_CONGESTION = 4; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.VehiclePosition.CongestionLevel) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class VehiclePosition extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.VehiclePosition'); | |
// optional .transit_realtime.TripDescriptor trip = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "trip"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripDescriptor'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:trip) | |
$descriptor->addField($f); | |
// optional .transit_realtime.VehicleDescriptor vehicle = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "vehicle"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\VehicleDescriptor'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:vehicle) | |
$descriptor->addField($f); | |
// optional .transit_realtime.Position position = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "position"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\Position'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:position) | |
$descriptor->addField($f); | |
// optional current_stop_sequence = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "current_stop_sequence"; | |
$f->type = 13; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:current_stop_sequence) | |
$descriptor->addField($f); | |
// optional stop_id = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "stop_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:stop_id) | |
$descriptor->addField($f); | |
// optional .transit_realtime.VehiclePosition.VehicleStopStatus current_status = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "current_status"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\VehiclePosition\VehicleStopStatus'; | |
$f->default = \transit_realtime\VehiclePosition\VehicleStopStatus::IN_TRANSIT_TO; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:current_status) | |
$descriptor->addField($f); | |
// optional timestamp = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "timestamp"; | |
$f->type = 4; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:timestamp) | |
$descriptor->addField($f); | |
// optional .transit_realtime.VehiclePosition.CongestionLevel congestion_level = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "congestion_level"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\VehiclePosition\CongestionLevel'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehiclePosition:congestion_level) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.VehiclePosition) | |
return $descriptor; | |
} | |
/** @var \transit_realtime\TripDescriptor */ | |
public $trip = null; | |
/** @var \transit_realtime\VehicleDescriptor */ | |
public $vehicle = null; | |
/** @var \transit_realtime\Position */ | |
public $position = null; | |
/** @var int */ | |
public $current_stop_sequence = null; | |
/** @var string */ | |
public $stop_id = null; | |
/** @var int - \transit_realtime\VehiclePosition\VehicleStopStatus */ | |
public $current_status = \transit_realtime\VehiclePosition\VehicleStopStatus::IN_TRANSIT_TO; | |
/** @var int */ | |
public $timestamp = null; | |
/** @var int - \transit_realtime\VehiclePosition\CongestionLevel */ | |
public $congestion_level = null; | |
/** | |
* Check if <trip> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTrip(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <trip> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearTrip(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <trip> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function getTrip(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <trip> value | |
* | |
* @param \transit_realtime\TripDescriptor $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setTrip(\transit_realtime\TripDescriptor $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <vehicle> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasVehicle(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <vehicle> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearVehicle(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <vehicle> value | |
* | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function getVehicle(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <vehicle> value | |
* | |
* @param \transit_realtime\VehicleDescriptor $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setVehicle(\transit_realtime\VehicleDescriptor $value){ | |
return $this->_set(8, $value); | |
} | |
/** | |
* Check if <position> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPosition(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <position> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearPosition(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <position> value | |
* | |
* @return \transit_realtime\Position | |
*/ | |
public function getPosition(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <position> value | |
* | |
* @param \transit_realtime\Position $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setPosition(\transit_realtime\Position $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <current_stop_sequence> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasCurrentStopSequence(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <current_stop_sequence> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearCurrentStopSequence(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <current_stop_sequence> value | |
* | |
* @return int | |
*/ | |
public function getCurrentStopSequence(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <current_stop_sequence> value | |
* | |
* @param int $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setCurrentStopSequence( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <stop_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStopId(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <stop_id> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearStopId(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <stop_id> value | |
* | |
* @return string | |
*/ | |
public function getStopId(){ | |
return $this->_get(7); | |
} | |
/** | |
* Set <stop_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setStopId( $value){ | |
return $this->_set(7, $value); | |
} | |
/** | |
* Check if <current_status> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasCurrentStatus(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <current_status> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearCurrentStatus(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <current_status> value | |
* | |
* @return int - \transit_realtime\VehiclePosition\VehicleStopStatus | |
*/ | |
public function getCurrentStatus(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <current_status> value | |
* | |
* @param int - \transit_realtime\VehiclePosition\VehicleStopStatus $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setCurrentStatus( $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <timestamp> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTimestamp(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <timestamp> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearTimestamp(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <timestamp> value | |
* | |
* @return int | |
*/ | |
public function getTimestamp(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <timestamp> value | |
* | |
* @param int $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setTimestamp( $value){ | |
return $this->_set(5, $value); | |
} | |
/** | |
* Check if <congestion_level> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasCongestionLevel(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <congestion_level> value | |
* | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function clearCongestionLevel(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <congestion_level> value | |
* | |
* @return int - \transit_realtime\VehiclePosition\CongestionLevel | |
*/ | |
public function getCongestionLevel(){ | |
return $this->_get(6); | |
} | |
/** | |
* Set <congestion_level> value | |
* | |
* @param int - \transit_realtime\VehiclePosition\CongestionLevel $value | |
* @return \transit_realtime\VehiclePosition | |
*/ | |
public function setCongestionLevel( $value){ | |
return $this->_set(6, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.VehiclePosition) | |
} | |
} | |
namespace transit_realtime\Alert { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.Alert) | |
class Cause { | |
const UNKNOWN_CAUSE = 1; | |
const OTHER_CAUSE = 2; | |
const TECHNICAL_PROBLEM = 3; | |
const STRIKE = 4; | |
const DEMONSTRATION = 5; | |
const ACCIDENT = 6; | |
const HOLIDAY = 7; | |
const WEATHER = 8; | |
const MAINTENANCE = 9; | |
const CONSTRUCTION = 10; | |
const POLICE_ACTIVITY = 11; | |
const MEDICAL_EMERGENCY = 12; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.Alert.Cause) | |
} | |
} | |
namespace transit_realtime\Alert { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.Alert) | |
class Effect { | |
const NO_SERVICE = 1; | |
const REDUCED_SERVICE = 2; | |
const SIGNIFICANT_DELAYS = 3; | |
const DETOUR = 4; | |
const ADDITIONAL_SERVICE = 5; | |
const MODIFIED_SERVICE = 6; | |
const OTHER_EFFECT = 7; | |
const UNKNOWN_EFFECT = 8; | |
const STOP_MOVED = 9; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.Alert.Effect) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class Alert extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.Alert'); | |
// repeated .transit_realtime.TimeRange active_period = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "active_period"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\transit_realtime\TimeRange'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:active_period) | |
$descriptor->addField($f); | |
// repeated .transit_realtime.EntitySelector informed_entity = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "informed_entity"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\transit_realtime\EntitySelector'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:informed_entity) | |
$descriptor->addField($f); | |
// optional .transit_realtime.Alert.Cause cause = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "cause"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\Alert\Cause'; | |
$f->default = \transit_realtime\Alert\Cause::UNKNOWN_CAUSE; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:cause) | |
$descriptor->addField($f); | |
// optional .transit_realtime.Alert.Effect effect = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "effect"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\Alert\Effect'; | |
$f->default = \transit_realtime\Alert\Effect::UNKNOWN_EFFECT; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:effect) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TranslatedString url = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "url"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TranslatedString'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:url) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TranslatedString header_text = 10 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 10; | |
$f->name = "header_text"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TranslatedString'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:header_text) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TranslatedString description_text = 11 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 11; | |
$f->name = "description_text"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TranslatedString'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Alert:description_text) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.Alert) | |
return $descriptor; | |
} | |
/** @var \transit_realtime\TimeRange[] */ | |
public $active_period = array(); | |
/** @var \transit_realtime\EntitySelector[] */ | |
public $informed_entity = array(); | |
/** @var int - \transit_realtime\Alert\Cause */ | |
public $cause = \transit_realtime\Alert\Cause::UNKNOWN_CAUSE; | |
/** @var int - \transit_realtime\Alert\Effect */ | |
public $effect = \transit_realtime\Alert\Effect::UNKNOWN_EFFECT; | |
/** @var \transit_realtime\TranslatedString */ | |
public $url = null; | |
/** @var \transit_realtime\TranslatedString */ | |
public $header_text = null; | |
/** @var \transit_realtime\TranslatedString */ | |
public $description_text = null; | |
/** | |
* Check if <active_period> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasActivePeriod(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <active_period> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearActivePeriod(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <active_period> value | |
* | |
* @param int $idx | |
* @return \transit_realtime\TimeRange | |
*/ | |
public function getActivePeriod($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <active_period> value | |
* | |
* @param \transit_realtime\TimeRange $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setActivePeriod(\transit_realtime\TimeRange $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <active_period> | |
* | |
* @return \transit_realtime\TimeRange[] | |
*/ | |
public function getActivePeriodList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <active_period> | |
* | |
* @param \transit_realtime\TimeRange $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function addActivePeriod(\transit_realtime\TimeRange $value){ | |
return $this->_add(1, $value); | |
} | |
/** | |
* Check if <informed_entity> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasInformedEntity(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <informed_entity> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearInformedEntity(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <informed_entity> value | |
* | |
* @param int $idx | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function getInformedEntity($idx = NULL){ | |
return $this->_get(5, $idx); | |
} | |
/** | |
* Set <informed_entity> value | |
* | |
* @param \transit_realtime\EntitySelector $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setInformedEntity(\transit_realtime\EntitySelector $value, $idx = NULL){ | |
return $this->_set(5, $value, $idx); | |
} | |
/** | |
* Get all elements of <informed_entity> | |
* | |
* @return \transit_realtime\EntitySelector[] | |
*/ | |
public function getInformedEntityList(){ | |
return $this->_get(5); | |
} | |
/** | |
* Add a new element to <informed_entity> | |
* | |
* @param \transit_realtime\EntitySelector $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function addInformedEntity(\transit_realtime\EntitySelector $value){ | |
return $this->_add(5, $value); | |
} | |
/** | |
* Check if <cause> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasCause(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <cause> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearCause(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <cause> value | |
* | |
* @return int - \transit_realtime\Alert\Cause | |
*/ | |
public function getCause(){ | |
return $this->_get(6); | |
} | |
/** | |
* Set <cause> value | |
* | |
* @param int - \transit_realtime\Alert\Cause $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setCause( $value){ | |
return $this->_set(6, $value); | |
} | |
/** | |
* Check if <effect> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEffect(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <effect> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearEffect(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <effect> value | |
* | |
* @return int - \transit_realtime\Alert\Effect | |
*/ | |
public function getEffect(){ | |
return $this->_get(7); | |
} | |
/** | |
* Set <effect> value | |
* | |
* @param int - \transit_realtime\Alert\Effect $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setEffect( $value){ | |
return $this->_set(7, $value); | |
} | |
/** | |
* Check if <url> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUrl(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <url> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearUrl(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <url> value | |
* | |
* @return \transit_realtime\TranslatedString | |
*/ | |
public function getUrl(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <url> value | |
* | |
* @param \transit_realtime\TranslatedString $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setUrl(\transit_realtime\TranslatedString $value){ | |
return $this->_set(8, $value); | |
} | |
/** | |
* Check if <header_text> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasHeaderText(){ | |
return $this->_has(10); | |
} | |
/** | |
* Clear <header_text> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearHeaderText(){ | |
return $this->_clear(10); | |
} | |
/** | |
* Get <header_text> value | |
* | |
* @return \transit_realtime\TranslatedString | |
*/ | |
public function getHeaderText(){ | |
return $this->_get(10); | |
} | |
/** | |
* Set <header_text> value | |
* | |
* @param \transit_realtime\TranslatedString $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setHeaderText(\transit_realtime\TranslatedString $value){ | |
return $this->_set(10, $value); | |
} | |
/** | |
* Check if <description_text> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDescriptionText(){ | |
return $this->_has(11); | |
} | |
/** | |
* Clear <description_text> value | |
* | |
* @return \transit_realtime\Alert | |
*/ | |
public function clearDescriptionText(){ | |
return $this->_clear(11); | |
} | |
/** | |
* Get <description_text> value | |
* | |
* @return \transit_realtime\TranslatedString | |
*/ | |
public function getDescriptionText(){ | |
return $this->_get(11); | |
} | |
/** | |
* Set <description_text> value | |
* | |
* @param \transit_realtime\TranslatedString $value | |
* @return \transit_realtime\Alert | |
*/ | |
public function setDescriptionText(\transit_realtime\TranslatedString $value){ | |
return $this->_set(11, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.Alert) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class TimeRange extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TimeRange'); | |
// optional start = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "start"; | |
$f->type = 4; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TimeRange:start) | |
$descriptor->addField($f); | |
// optional end = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "end"; | |
$f->type = 4; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TimeRange:end) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TimeRange) | |
return $descriptor; | |
} | |
/** @var int */ | |
public $start = null; | |
/** @var int */ | |
public $end = null; | |
/** | |
* Check if <start> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStart(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <start> value | |
* | |
* @return \transit_realtime\TimeRange | |
*/ | |
public function clearStart(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <start> value | |
* | |
* @return int | |
*/ | |
public function getStart(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <start> value | |
* | |
* @param int $value | |
* @return \transit_realtime\TimeRange | |
*/ | |
public function setStart( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <end> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEnd(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <end> value | |
* | |
* @return \transit_realtime\TimeRange | |
*/ | |
public function clearEnd(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <end> value | |
* | |
* @return int | |
*/ | |
public function getEnd(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <end> value | |
* | |
* @param int $value | |
* @return \transit_realtime\TimeRange | |
*/ | |
public function setEnd( $value){ | |
return $this->_set(2, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TimeRange) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class Position extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.Position'); | |
// required latitude = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "latitude"; | |
$f->type = 2; | |
$f->rule = 2; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Position:latitude) | |
$descriptor->addField($f); | |
// required longitude = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "longitude"; | |
$f->type = 2; | |
$f->rule = 2; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Position:longitude) | |
$descriptor->addField($f); | |
// optional bearing = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "bearing"; | |
$f->type = 2; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Position:bearing) | |
$descriptor->addField($f); | |
// optional odometer = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "odometer"; | |
$f->type = 1; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Position:odometer) | |
$descriptor->addField($f); | |
// optional speed = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "speed"; | |
$f->type = 2; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.Position:speed) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.Position) | |
return $descriptor; | |
} | |
/** @var float */ | |
public $latitude = null; | |
/** @var float */ | |
public $longitude = null; | |
/** @var float */ | |
public $bearing = null; | |
/** @var float */ | |
public $odometer = null; | |
/** @var float */ | |
public $speed = null; | |
/** | |
* Check if <latitude> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLatitude(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <latitude> value | |
* | |
* @return \transit_realtime\Position | |
*/ | |
public function clearLatitude(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <latitude> value | |
* | |
* @return float | |
*/ | |
public function getLatitude(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <latitude> value | |
* | |
* @param float $value | |
* @return \transit_realtime\Position | |
*/ | |
public function setLatitude( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <longitude> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLongitude(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <longitude> value | |
* | |
* @return \transit_realtime\Position | |
*/ | |
public function clearLongitude(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <longitude> value | |
* | |
* @return float | |
*/ | |
public function getLongitude(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <longitude> value | |
* | |
* @param float $value | |
* @return \transit_realtime\Position | |
*/ | |
public function setLongitude( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <bearing> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasBearing(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <bearing> value | |
* | |
* @return \transit_realtime\Position | |
*/ | |
public function clearBearing(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <bearing> value | |
* | |
* @return float | |
*/ | |
public function getBearing(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <bearing> value | |
* | |
* @param float $value | |
* @return \transit_realtime\Position | |
*/ | |
public function setBearing( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <odometer> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOdometer(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <odometer> value | |
* | |
* @return \transit_realtime\Position | |
*/ | |
public function clearOdometer(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <odometer> value | |
* | |
* @return float | |
*/ | |
public function getOdometer(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <odometer> value | |
* | |
* @param float $value | |
* @return \transit_realtime\Position | |
*/ | |
public function setOdometer( $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <speed> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSpeed(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <speed> value | |
* | |
* @return \transit_realtime\Position | |
*/ | |
public function clearSpeed(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <speed> value | |
* | |
* @return float | |
*/ | |
public function getSpeed(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <speed> value | |
* | |
* @param float $value | |
* @return \transit_realtime\Position | |
*/ | |
public function setSpeed( $value){ | |
return $this->_set(5, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.Position) | |
} | |
} | |
namespace transit_realtime\TripDescriptor { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.TripDescriptor) | |
class ScheduleRelationship { | |
const SCHEDULED = 0; | |
const ADDED = 1; | |
const UNSCHEDULED = 2; | |
const CANCELED = 3; | |
const REPLACEMENT = 5; | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TripDescriptor.ScheduleRelationship) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class TripDescriptor extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TripDescriptor'); | |
// optional trip_id = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "trip_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripDescriptor:trip_id) | |
$descriptor->addField($f); | |
// optional route_id = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "route_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripDescriptor:route_id) | |
$descriptor->addField($f); | |
// optional start_time = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "start_time"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripDescriptor:start_time) | |
$descriptor->addField($f); | |
// optional start_date = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "start_date"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripDescriptor:start_date) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TripDescriptor.ScheduleRelationship schedule_relationship = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "schedule_relationship"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripDescriptor\ScheduleRelationship'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TripDescriptor:schedule_relationship) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TripDescriptor) | |
return $descriptor; | |
} | |
/** @var string */ | |
public $trip_id = null; | |
/** @var string */ | |
public $route_id = null; | |
/** @var string */ | |
public $start_time = null; | |
/** @var string */ | |
public $start_date = null; | |
/** @var int - \transit_realtime\TripDescriptor\ScheduleRelationship */ | |
public $schedule_relationship = null; | |
/** | |
* Check if <trip_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTripId(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <trip_id> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function clearTripId(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <trip_id> value | |
* | |
* @return string | |
*/ | |
public function getTripId(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <trip_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function setTripId( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <route_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasRouteId(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <route_id> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function clearRouteId(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <route_id> value | |
* | |
* @return string | |
*/ | |
public function getRouteId(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <route_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function setRouteId( $value){ | |
return $this->_set(5, $value); | |
} | |
/** | |
* Check if <start_time> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStartTime(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <start_time> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function clearStartTime(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <start_time> value | |
* | |
* @return string | |
*/ | |
public function getStartTime(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <start_time> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function setStartTime( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <start_date> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStartDate(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <start_date> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function clearStartDate(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <start_date> value | |
* | |
* @return string | |
*/ | |
public function getStartDate(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <start_date> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function setStartDate( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <schedule_relationship> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasScheduleRelationship(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <schedule_relationship> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function clearScheduleRelationship(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <schedule_relationship> value | |
* | |
* @return int - \transit_realtime\TripDescriptor\ScheduleRelationship | |
*/ | |
public function getScheduleRelationship(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <schedule_relationship> value | |
* | |
* @param int - \transit_realtime\TripDescriptor\ScheduleRelationship $value | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function setScheduleRelationship( $value){ | |
return $this->_set(4, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TripDescriptor) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class VehicleDescriptor extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.VehicleDescriptor'); | |
// optional id = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehicleDescriptor:id) | |
$descriptor->addField($f); | |
// optional label = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "label"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehicleDescriptor:label) | |
$descriptor->addField($f); | |
// optional license_plate = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "license_plate"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.VehicleDescriptor:license_plate) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.VehicleDescriptor) | |
return $descriptor; | |
} | |
/** @var string */ | |
public $id = null; | |
/** @var string */ | |
public $label = null; | |
/** @var string */ | |
public $license_plate = null; | |
/** | |
* Check if <id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasId(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <id> value | |
* | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function clearId(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <id> value | |
* | |
* @return string | |
*/ | |
public function getId(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function setId( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <label> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLabel(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <label> value | |
* | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function clearLabel(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <label> value | |
* | |
* @return string | |
*/ | |
public function getLabel(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <label> value | |
* | |
* @param string $value | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function setLabel( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <license_plate> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLicensePlate(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <license_plate> value | |
* | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function clearLicensePlate(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <license_plate> value | |
* | |
* @return string | |
*/ | |
public function getLicensePlate(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <license_plate> value | |
* | |
* @param string $value | |
* @return \transit_realtime\VehicleDescriptor | |
*/ | |
public function setLicensePlate( $value){ | |
return $this->_set(3, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.VehicleDescriptor) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class EntitySelector extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.EntitySelector'); | |
// optional agency_id = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "agency_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.EntitySelector:agency_id) | |
$descriptor->addField($f); | |
// optional route_id = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "route_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.EntitySelector:route_id) | |
$descriptor->addField($f); | |
// optional route_type = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "route_type"; | |
$f->type = 5; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.EntitySelector:route_type) | |
$descriptor->addField($f); | |
// optional .transit_realtime.TripDescriptor trip = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "trip"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = '\transit_realtime\TripDescriptor'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.EntitySelector:trip) | |
$descriptor->addField($f); | |
// optional stop_id = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "stop_id"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.EntitySelector:stop_id) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.EntitySelector) | |
return $descriptor; | |
} | |
/** @var string */ | |
public $agency_id = null; | |
/** @var string */ | |
public $route_id = null; | |
/** @var int */ | |
public $route_type = null; | |
/** @var \transit_realtime\TripDescriptor */ | |
public $trip = null; | |
/** @var string */ | |
public $stop_id = null; | |
/** | |
* Check if <agency_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasAgencyId(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <agency_id> value | |
* | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function clearAgencyId(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <agency_id> value | |
* | |
* @return string | |
*/ | |
public function getAgencyId(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <agency_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function setAgencyId( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <route_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasRouteId(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <route_id> value | |
* | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function clearRouteId(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <route_id> value | |
* | |
* @return string | |
*/ | |
public function getRouteId(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <route_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function setRouteId( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <route_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasRouteType(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <route_type> value | |
* | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function clearRouteType(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <route_type> value | |
* | |
* @return int | |
*/ | |
public function getRouteType(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <route_type> value | |
* | |
* @param int $value | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function setRouteType( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <trip> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTrip(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <trip> value | |
* | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function clearTrip(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <trip> value | |
* | |
* @return \transit_realtime\TripDescriptor | |
*/ | |
public function getTrip(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <trip> value | |
* | |
* @param \transit_realtime\TripDescriptor $value | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function setTrip(\transit_realtime\TripDescriptor $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <stop_id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStopId(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <stop_id> value | |
* | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function clearStopId(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <stop_id> value | |
* | |
* @return string | |
*/ | |
public function getStopId(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <stop_id> value | |
* | |
* @param string $value | |
* @return \transit_realtime\EntitySelector | |
*/ | |
public function setStopId( $value){ | |
return $this->_set(5, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.EntitySelector) | |
} | |
} | |
namespace transit_realtime\TranslatedString { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime.TranslatedString) | |
class Translation extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TranslatedString.Translation'); | |
// required text = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "text"; | |
$f->type = 9; | |
$f->rule = 2; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TranslatedString.Translation:text) | |
$descriptor->addField($f); | |
// optional language = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "language"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TranslatedString.Translation:language) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TranslatedString.Translation) | |
return $descriptor; | |
} | |
/** @var string */ | |
public $text = null; | |
/** @var string */ | |
public $language = null; | |
/** | |
* Check if <text> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasText(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <text> value | |
* | |
* @return \transit_realtime\TranslatedString\Translation | |
*/ | |
public function clearText(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <text> value | |
* | |
* @return string | |
*/ | |
public function getText(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <text> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TranslatedString\Translation | |
*/ | |
public function setText( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <language> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLanguage(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <language> value | |
* | |
* @return \transit_realtime\TranslatedString\Translation | |
*/ | |
public function clearLanguage(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <language> value | |
* | |
* @return string | |
*/ | |
public function getLanguage(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <language> value | |
* | |
* @param string $value | |
* @return \transit_realtime\TranslatedString\Translation | |
*/ | |
public function setLanguage( $value){ | |
return $this->_set(2, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TranslatedString.Translation) | |
} | |
} | |
namespace transit_realtime { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_transit_realtime) | |
class TranslatedString extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'transit_realtime.TranslatedString'); | |
// repeated .transit_realtime.TranslatedString.Translation translation = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "translation"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\transit_realtime\TranslatedString\Translation'; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_transit_realtime.TranslatedString:translation) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_transit_realtime.TranslatedString) | |
return $descriptor; | |
} | |
/** @var \transit_realtime\TranslatedString\Translation[] */ | |
public $translation = array(); | |
/** | |
* Check if <translation> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTranslation(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <translation> value | |
* | |
* @return \transit_realtime\TranslatedString | |
*/ | |
public function clearTranslation(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <translation> value | |
* | |
* @param int $idx | |
* @return \transit_realtime\TranslatedString\Translation | |
*/ | |
public function getTranslation($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <translation> value | |
* | |
* @param \transit_realtime\TranslatedString\Translation $value | |
* @return \transit_realtime\TranslatedString | |
*/ | |
public function setTranslation(\transit_realtime\TranslatedString\Translation $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <translation> | |
* | |
* @return \transit_realtime\TranslatedString\Translation[] | |
*/ | |
public function getTranslationList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <translation> | |
* | |
* @param \transit_realtime\TranslatedString\Translation $value | |
* @return \transit_realtime\TranslatedString | |
*/ | |
public function addTranslation(\transit_realtime\TranslatedString\Translation $value){ | |
return $this->_add(1, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_transit_realtime.TranslatedString) | |
} | |
} | |
// Copyright 2010 Google Inc | |
// | |
// The content of this file is licensed under the Creative Commons Attribution | |
// 3.0 License. | |
// | |
// Protocol definition file for GTFS-realtime. | |
// | |
// GTFS-realtime lets transit agencies provide consumers with realtime | |
// information about disruptions to their service (stations closed, lines not | |
// operating, important delays etc), location of their vehicles and expected | |
// arrival times. | |
// | |
// This protocol is published on http://code.google.com/transit/realtime/ . | |
syntax = "proto2"; | |
option cc_api_version = 2; | |
option py_api_version = 1; | |
option java_package = "com.google.transit.realtime"; | |
package transit_realtime; | |
// The contents of a feed message. | |
// A feed is a continuous stream of feed messages. Each message in the stream is | |
// obtained as a response to an appropriate HTTP GET request. | |
// A realtime feed is always defined with relation to an existing GTFS feed. | |
// All the entity ids are resolved with respect to the GTFS feed. | |
// | |
// A feed depends on some external configuration: | |
// - The corresponding GTFS feed. | |
// - Feed application (updates, positions or alerts). A feed should contain only | |
// items of one specified application; all the other entities will be ignored. | |
// - Polling frequency | |
message FeedMessage { | |
// Metadata about this feed and feed message. | |
required FeedHeader header = 1; | |
// Contents of the feed. | |
repeated FeedEntity entity = 2; | |
} | |
// Metadata about a feed, included in feed messages. | |
message FeedHeader { | |
// Version of the feed specification. | |
// The current version is 1.0. | |
required string gtfs_realtime_version = 1; | |
// Determines whether the current fetch is incremental. | |
enum Incrementality { | |
FULL_DATASET = 0; | |
DIFFERENTIAL = 1; | |
} | |
optional Incrementality incrementality = 2 [default = FULL_DATASET]; | |
// This timestamp identifies the moment when the content of this feed has been | |
// created (in server time). In POSIX time (i.e., number of seconds since | |
// January 1st 1970 00:00:00 UTC). | |
optional uint64 timestamp = 3; | |
} | |
// A definition (or update) of an entity in the transit feed. | |
message FeedEntity { | |
// The ids are used only to provide incrementality support. The id should be | |
// unique within a FeedMessage. Consequent FeedMessages may contain | |
// FeedEntities with the same id. In case of a DIFFERENTIAL update the new | |
// FeedEntity with some id will replace the old FeedEntity with the same id | |
// (or delete it - see is_deleted below). | |
// The actual GTFS entities (e.g. stations, routes, trips) referenced by the | |
// feed must be specified by explicit selectors (see EntitySelector below for | |
// more info). | |
required string id = 1; | |
// Whether this entity is to be deleted. Relevant only for incremental | |
// fetches. | |
optional bool is_deleted = 2 [default = false]; | |
// Data about the entity itself. Exactly one of the following fields must be | |
// present (unless the entity is being deleted). | |
optional TripUpdate trip_update = 3; | |
optional VehiclePosition vehicle = 4; | |
optional Alert alert = 5; | |
} | |
// | |
// Entities used in the feed. | |
// | |
// Realtime update of the progress of a vehicle along a trip. | |
// Depending on the value of ScheduleRelationship, a TripUpdate can specify: | |
// - A trip that proceeds along the schedule. | |
// - A trip that proceeds along a route but has no fixed schedule. | |
// - A trip that have been added or removed with regard to schedule. | |
// | |
// The updates can be for future, predicted arrival/departure events, or for | |
// past events that already occurred. | |
// Normally, updates should get more precise and more certain (see | |
// uncertainty below) as the events gets closer to current time. | |
// Even if that is not possible, the information for past events should be | |
// precise and certain. In particular, if an update points to time in the past | |
// but its update's uncertainty is not 0, the client should conclude that the | |
// update is a (wrong) prediction and that the trip has not completed yet. | |
// | |
// Note that the update can describe a trip that is already completed. | |
// To this end, it is enough to provide an update for the last stop of the trip. | |
// If the time of that is in the past, the client will conclude from that that | |
// the whole trip is in the past (it is possible, although inconsequential, to | |
// also provide updates for preceding stops). | |
// This option is most relevant for a trip that has completed ahead of schedule, | |
// but according to the schedule, the trip is still proceeding at the current | |
// time. Removing the updates for this trip could make the client assume | |
// that the trip is still proceeding. | |
// Note that the feed provider is allowed, but not required, to purge past | |
// updates - this is one case where this would be practically useful. | |
message TripUpdate { | |
// The Trip that this message applies to. There can be at most one | |
// TripUpdate entity for each actual trip instance. | |
// If there is none, that means there is no prediction information available. | |
// It does *not* mean that the trip is progressing according to schedule. | |
required TripDescriptor trip = 1; | |
// Additional information on the vehicle that is serving this trip. | |
optional VehicleDescriptor vehicle = 3; | |
// Timing information for a single predicted event (either arrival or | |
// departure). | |
// Timing consists of delay and/or estimated time, and uncertainty. | |
// - delay should be used when the prediction is given relative to some | |
// existing schedule in GTFS. | |
// - time should be given whether there is a predicted schedule or not. If | |
// both time and delay are specified, time will take precedence | |
// (although normally, time, if given for a scheduled trip, should be | |
// equal to scheduled time in GTFS + delay). | |
// | |
// Uncertainty applies equally to both time and delay. | |
// The uncertainty roughly specifies the expected error in true delay (but | |
// note, we don't yet define its precise statistical meaning). It's possible | |
// for the uncertainty to be 0, for example for trains that are driven under | |
// computer timing control. | |
message StopTimeEvent { | |
// Delay (in seconds) can be positive (meaning that the vehicle is late) or | |
// negative (meaning that the vehicle is ahead of schedule). Delay of 0 | |
// means that the vehicle is exactly on time. | |
optional int32 delay = 1; | |
// Event as absolute time. | |
// In Unix time (i.e., number of seconds since January 1st 1970 00:00:00 | |
// UTC). | |
optional int64 time = 2; | |
// If uncertainty is omitted, it is interpreted as unknown. | |
// If the prediction is unknown or too uncertain, the delay (or time) field | |
// should be empty. In such case, the uncertainty field is ignored. | |
// To specify a completely certain prediction, set its uncertainty to 0. | |
optional int32 uncertainty = 3; | |
} | |
// Realtime update for arrival and/or departure events for a given stop on a | |
// trip. Updates can be supplied for both past and future events. | |
// The producer is allowed, although not required, to drop past events. | |
message StopTimeUpdate { | |
// The update is linked to a specific stop either through stop_sequence or | |
// stop_id, so one of the fields below must necessarily be set. | |
// See the documentation in TripDescriptor for more information. | |
// Must be the same as in stop_times.txt in the corresponding GTFS feed. | |
optional uint32 stop_sequence = 1; | |
// Must be the same as in stops.txt in the corresponding GTFS feed. | |
optional string stop_id = 4; | |
optional StopTimeEvent arrival = 2; | |
optional StopTimeEvent departure = 3; | |
// The relation between this StopTime and the static schedule. | |
enum ScheduleRelationship { | |
// The vehicle is proceeding in accordance with its static schedule of | |
// stops, although not necessarily according to the times of the schedule. | |
// At least one of arrival and departure must be provided. If the schedule | |
// for this stop contains both arrival and departure times then so must | |
// this update. An update with only an arrival, say, where the schedule | |
// has both, indicates that the trip is terminating early at this stop. | |
SCHEDULED = 0; | |
// The stop is skipped, i.e., the vehicle will not stop at this stop. | |
// Arrival and departure are optional. | |
SKIPPED = 1; | |
// No data is given for this stop. The main intention for this value is to | |
// give the predictions only for part of a trip, i.e., if the last update | |
// for a trip has a NO_DATA specifier, then StopTimes for the rest of the | |
// stops in the trip are considered to be unspecified as well. | |
// Neither arrival nor departure should be supplied. | |
NO_DATA = 2; | |
} | |
optional ScheduleRelationship schedule_relationship = 5 | |
[default = SCHEDULED]; | |
} | |
// Updates to StopTimes for the trip (both future, i.e., predictions, and in | |
// some cases, past ones, i.e., those that already happened). | |
// The updates must be sorted by stop_sequence, and apply for all the | |
// following stops of the trip up to the next specified one. | |
// | |
// Example 1: | |
// For a trip with 20 stops, a StopTimeUpdate with arrival delay and departure | |
// delay of 0 for stop_sequence of the current stop means that the trip is | |
// exactly on time. | |
// | |
// Example 2: | |
// For the same trip instance, 3 StopTimeUpdates are provided: | |
// - delay of 5 min for stop_sequence 3 | |
// - delay of 1 min for stop_sequence 8 | |
// - delay of unspecified duration for stop_sequence 10 | |
// This will be interpreted as: | |
// - stop_sequences 3,4,5,6,7 have delay of 5 min. | |
// - stop_sequences 8,9 have delay of 1 min. | |
// - stop_sequences 10,... have unknown delay. | |
repeated StopTimeUpdate stop_time_update = 2; | |
} | |
// Realtime positioning information for a given vehicle. | |
message VehiclePosition { | |
// The Trip that this vehicle is serving. | |
// Can be empty or partial if the vehicle can not be identified with a given | |
// trip instance. | |
optional TripDescriptor trip = 1; | |
// Additional information on the vehicle that is serving this trip. | |
optional VehicleDescriptor vehicle = 8; | |
// Current position of this vehicle. | |
optional Position position = 2; | |
// The stop sequence index of the current stop. The meaning of | |
// current_stop_sequence (i.e., the stop that it refers to) is determined by | |
// current_status. | |
// If current_status is missing IN_TRANSIT_TO is assumed. | |
optional uint32 current_stop_sequence = 3; | |
// Identifies the current stop. The value must be the same as in stops.txt in | |
// the corresponding GTFS feed. | |
optional string stop_id = 7; | |
enum VehicleStopStatus { | |
// The vehicle is just about to arrive at the stop (on a stop | |
// display, the vehicle symbol typically flashes). | |
INCOMING_AT = 0; | |
// The vehicle is standing at the stop. | |
STOPPED_AT = 1; | |
// The vehicle has departed and is in transit to the next stop. | |
IN_TRANSIT_TO = 2; | |
} | |
// The exact status of the vehicle with respect to the current stop. | |
// Ignored if current_stop_sequence is missing. | |
optional VehicleStopStatus current_status = 4 [default = IN_TRANSIT_TO]; | |
// Moment at which the vehicle's position was measured. In POSIX time | |
// (i.e., number of seconds since January 1st 1970 00:00:00 UTC). | |
optional uint64 timestamp = 5; | |
// Congestion level that is affecting this vehicle. | |
enum CongestionLevel { | |
UNKNOWN_CONGESTION_LEVEL = 0; | |
RUNNING_SMOOTHLY = 1; | |
STOP_AND_GO = 2; | |
CONGESTION = 3; | |
SEVERE_CONGESTION = 4; // People leaving their cars. | |
} | |
optional CongestionLevel congestion_level = 6; | |
} | |
// An alert, indicating some sort of incident in the public transit network. | |
message Alert { | |
// Time when the alert should be shown to the user. If missing, the | |
// alert will be shown as long as it appears in the feed. | |
// If multiple ranges are given, the alert will be shown during all of them. | |
repeated TimeRange active_period = 1; | |
// Entities whose users we should notify of this alert. | |
repeated EntitySelector informed_entity = 5; | |
// Cause of this alert. | |
enum Cause { | |
UNKNOWN_CAUSE = 1; | |
OTHER_CAUSE = 2; // Not machine-representable. | |
TECHNICAL_PROBLEM = 3; | |
STRIKE = 4; // Public transit agency employees stopped working. | |
DEMONSTRATION = 5; // People are blocking the streets. | |
ACCIDENT = 6; | |
HOLIDAY = 7; | |
WEATHER = 8; | |
MAINTENANCE = 9; | |
CONSTRUCTION = 10; | |
POLICE_ACTIVITY = 11; | |
MEDICAL_EMERGENCY = 12; | |
} | |
optional Cause cause = 6 [default = UNKNOWN_CAUSE]; | |
// What is the effect of this problem on the affected entity. | |
enum Effect { | |
NO_SERVICE = 1; | |
REDUCED_SERVICE = 2; | |
// We don't care about INsignificant delays: they are hard to detect, have | |
// little impact on the user, and would clutter the results as they are too | |
// frequent. | |
SIGNIFICANT_DELAYS = 3; | |
DETOUR = 4; | |
ADDITIONAL_SERVICE = 5; | |
MODIFIED_SERVICE = 6; | |
OTHER_EFFECT = 7; | |
UNKNOWN_EFFECT = 8; | |
STOP_MOVED = 9; | |
} | |
optional Effect effect = 7 [default = UNKNOWN_EFFECT]; | |
// The URL which provides additional information about the alert. | |
optional TranslatedString url = 8; | |
// Alert header. Contains a short summary of the alert text. | |
optional TranslatedString header_text = 10; | |
// Full description for the alert. The information in the description | |
// should add to the information of the header. | |
optional TranslatedString description_text = 11; | |
} | |
// | |
// Low level data structures used above. | |
// | |
// A time interval. | |
message TimeRange { | |
// Start time, in POSIX time (i.e., number of seconds since January 1st 1970 | |
// 00:00:00 UTC). | |
// If missing, the interval starts at minus infinity. | |
optional uint64 start = 1; | |
// End time, in POSIX time (i.e., number of seconds since January 1st 1970 | |
// 00:00:00 UTC). | |
// If missing, the interval ends at plus infinity. | |
optional uint64 end = 2; | |
} | |
// A position. | |
message Position { | |
// Degrees North, in the WGS-84 coordinate system. | |
required float latitude = 1; | |
// Degrees East, in the WGS-84 coordinate system. | |
required float longitude = 2; | |
// Bearing, in degrees, clockwise from North, i.e., 0 is North and 90 is East. | |
// This can be the compass bearing, or the direction towards the next stop | |
// or intermediate location. | |
// This should not be direction deduced from the sequence of previous | |
// positions, which can be computed from previous data. | |
optional float bearing = 3; | |
// Odometer value, in meters. | |
optional double odometer = 4; | |
// Momentary speed measured by the vehicle, in meters per second. | |
optional float speed = 5; | |
} | |
// A descriptor that identifies an instance of a GTFS trip, or all instances of | |
// a trip along a route. | |
// - To specify a single trip instance, the trip_id (and if necessary, | |
// start_time) is set. If route_id is also set, then it should be same as one | |
// that the given trip corresponds to. | |
// - To specify all the trips along a given route, only the route_id should be | |
// set. Note that if the trip_id is not known, then stop sequence ids in | |
// TripUpdate are not sufficient, and stop_ids must be provided as well. In | |
// addition, absolute arrival/departure times must be provided. | |
message TripDescriptor { | |
// The trip_id from the GTFS feed that this selector refers to. | |
// For non frequency expanded trips, this field is enough to uniquely identify | |
// the trip. For frequency expanded, start_time and start_date might also be | |
// necessary. | |
optional string trip_id = 1; | |
// The route_id from the GTFS that this selector refers to. | |
optional string route_id = 5; | |
// The scheduled start time of this trip instance. | |
// This field should be given only if the trip is frequency-expanded in the | |
// GTFS feed. The value must precisely correspond to start_time specified for | |
// the route in the GTFS feed plus some multiple of headway_secs. | |
// Format of the field is same as that of GTFS/frequencies.txt/start_time, | |
// e.g., 11:15:35 or 25:15:35. | |
optional string start_time = 2; | |
// The scheduled start date of this trip instance. | |
// Must be provided to disambiguate trips that are so late as to collide with | |
// a scheduled trip on a next day. For example, for a train that departs 8:00 | |
// and 20:00 every day, and is 12 hours late, there would be two distinct | |
// trips on the same time. | |
// This field can be provided but is not mandatory for schedules in which such | |
// collisions are impossible - for example, a service running on hourly | |
// schedule where a vehicle that is one hour late is not considered to be | |
// related to schedule anymore. | |
// In YYYYMMDD format. | |
optional string start_date = 3; | |
// The relation between this trip and the static schedule. If a trip is done | |
// in accordance with temporary schedule, not reflected in GTFS, then it | |
// shouldn't be marked as SCHEDULED, but likely as ADDED. | |
enum ScheduleRelationship { | |
// Trip that is running in accordance with its GTFS schedule, or is close | |
// enough to the scheduled trip to be associated with it. | |
SCHEDULED = 0; | |
// An extra trip that was added in addition to a running schedule, for | |
// example, to replace a broken vehicle or to respond to sudden passenger | |
// load. | |
ADDED = 1; | |
// A trip that is running with no schedule associated to it, for example, if | |
// there is no schedule at all. | |
UNSCHEDULED = 2; | |
// A trip that existed in the schedule but was removed. | |
CANCELED = 3; | |
// A trip that replaces a portion of static schedule. | |
// If the trip selector identifies a certain trip instance, then only that | |
// instance is replaced. If the selector identifies a route, then all the | |
// trips along that route are replaced. | |
// | |
// The replacement applies only to the portion of the trip supplied. For | |
// instance, consider a route that goes through stops A,B,C,D,E,F, and a | |
// REPLACEMENT trip provides data for stops A,B,C. Then, the times for stops | |
// D,E,F are still taken from the static schedule. | |
// | |
// A feed might supply several REPLACEMENT trips. In this case, the portion | |
// of static schedule that is replaced is the union of what is defined by | |
// all the feeds. Normally, all the REPLACEMENT trips should either | |
// correspond to the same route or to individual trip instances. | |
REPLACEMENT = 5; | |
} | |
optional ScheduleRelationship schedule_relationship = 4; | |
} | |
// Identification information for the vehicle performing the trip. | |
message VehicleDescriptor { | |
// Internal system identification of the vehicle. Should be unique per | |
// vehicle, and can be used for tracking the vehicle as it proceeds through | |
// the system. | |
optional string id = 1; | |
// User visible label, i.e., something that must be shown to the passenger to | |
// help identify the correct vehicle. | |
optional string label = 2; | |
// The license plate of the vehicle. | |
optional string license_plate = 3; | |
} | |
// A selector for an entity in a GTFS feed. | |
message EntitySelector { | |
// The values of the fields should correspond to the appropriate fields in the | |
// GTFS feed. | |
// At least one specifier must be given. If several are given, then the | |
// matching has to apply to all the given specifiers. | |
optional string agency_id = 1; | |
optional string route_id = 2; | |
// corresponds to route_type in GTFS. | |
optional int32 route_type = 3; | |
optional TripDescriptor trip = 4; | |
optional string stop_id = 5; | |
} | |
// An internationalized message containing per-language versions of a snippet of | |
// text or a URL. | |
// One of the strings from a message will be picked up. The resolution proceeds | |
// as follows: | |
// 1. If the UI language matches the language code of a translation, | |
// the first matching translation is picked. | |
// 2. If a default UI language (e.g., English) matches the language code of a | |
// translation, the first matching translation is picked. | |
// 3. If some translation has an unspecified language code, that translation is | |
// picked. | |
message TranslatedString { | |
message Translation { | |
// A UTF-8 string containing the message. | |
required string text = 1; | |
// BCP-47 language code. Can be omitted if the language is unknown or if | |
// no i18n is done at all for the feed. At most one translation is | |
// allowed to have an unspecified language tag. | |
optional string language = 2; | |
} | |
// At least one translation must be provided. | |
repeated Translation translation = 1; | |
} | |
<?php | |
namespace DrSlump; | |
use DrSlump\Protobuf; | |
class Protobuf | |
{ | |
const VERSION = '@package_version@'; | |
const RULE_OPTIONAL = 1; | |
const RULE_REQUIRED = 2; | |
const RULE_REPEATED = 3; | |
const RULE_UNKNOWN = -1; | |
const TYPE_DOUBLE = 1; | |
const TYPE_FLOAT = 2; | |
const TYPE_INT64 = 3; | |
const TYPE_UINT64 = 4; | |
const TYPE_INT32 = 5; | |
const TYPE_FIXED64 = 6; | |
const TYPE_FIXED32 = 7; | |
const TYPE_BOOL = 8; | |
const TYPE_STRING = 9; | |
const TYPE_GROUP = 10; | |
const TYPE_MESSAGE = 11; | |
const TYPE_BYTES = 12; | |
const TYPE_UINT32 = 13; | |
const TYPE_ENUM = 14; | |
const TYPE_SFIXED32 = 15; | |
const TYPE_SFIXED64 = 16; | |
const TYPE_SINT32 = 17; | |
const TYPE_SINT64 = 18; | |
const TYPE_UNKNOWN = -1; | |
static protected $codecs = array(); | |
/** | |
* Setup SPL autoloader for Protobuf library classes | |
* | |
* @static | |
* @return void | |
*/ | |
static public function autoload() | |
{ | |
spl_autoload_register(function($class){ | |
$prefix = __CLASS__ . '\\'; | |
if (strpos($class, $prefix) === 0) { | |
// Remove vendor from name | |
$class = substr($class, strlen(__NAMESPACE__)+1); | |
// Convert namespace separator to directory ones | |
$class = str_replace('\\', DIRECTORY_SEPARATOR, $class); | |
// Prefix with this file's directory | |
$class = __DIR__ . DIRECTORY_SEPARATOR . $class; | |
include($class . '.php'); | |
return true; | |
} | |
return false; | |
}); | |
} | |
/** | |
* Obtain an instance of the descriptor's registry | |
* | |
* @static | |
* @return Protobuf\Registry | |
*/ | |
static public function getRegistry() | |
{ | |
static $registry = NULL; | |
if (NULL === $registry) { | |
$registry = new Protobuf\Registry(); | |
} | |
return $registry; | |
} | |
static public function getCodec($codec = null) | |
{ | |
if ($codec instanceof Protobuf\CodecInterface) { | |
return $codec; | |
} | |
// Bootstrap the library's default codec if none is available | |
if (!isset(self::$codecs['default'])) { | |
$default = new Protobuf\Codec\Binary(); | |
self::registerCodec('default', $default); | |
self::registerCodec('binary', $default); | |
} | |
if (is_string($codec)) { | |
$codec = strtolower($codec); | |
if (!isset(self::$codecs[$codec])) { | |
throw new Protobuf\Exception('No codec found by name "' . $codec . '"'); | |
} | |
return self::$codecs[$codec]; | |
} | |
return self::getCodec('default'); | |
} | |
static public function setDefaultCodec($codec) | |
{ | |
if (is_string($codec)) { | |
$codec = self::getCodec($codec); | |
} | |
if ($codec instanceof Protobuf\CodecInterface) { | |
self::registerCodec('default', $codec); | |
} else { | |
throw new Protobuf\Exception('Codec must implement DrSlump\Protobuf\CodecInterface'); | |
} | |
} | |
static public function registerCodec($name, Protobuf\CodecInterface $codec) | |
{ | |
$name = strtolower($name); | |
self::$codecs[$name] = $codec; | |
} | |
static public function unregisterCodec($name) | |
{ | |
$name = strtolower($name); | |
if (isset(self::$codecs[$name])) { | |
unset(self::$codecs[$name]); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Encodes a message using the default codec | |
* | |
* @static | |
* @param \DrSlump\Protobuf\Message $message | |
* @return string | |
*/ | |
static public function encode(Protobuf\Message $message) | |
{ | |
$codec = self::getCodec(); | |
return $codec->encode($message); | |
} | |
/** | |
* @static | |
* @param String|Message $message | |
* @param String $data | |
* @return \DrSlump\Protobuf\Message | |
*/ | |
static public function decode($message, $data) | |
{ | |
if (is_string($message)) { | |
$message = '\\' . ltrim($message, '\\'); | |
$message = new $message; | |
} | |
$codec = self::getCodec(); | |
return $codec->decode($message, $data); | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf; | |
use DrSlump\Protobuf; | |
abstract class AnnotatedMessage extends Message | |
{ | |
static public function descriptor() | |
{ | |
$class = get_called_class(); | |
// Instantiate a new descriptor | |
$descriptor = new Descriptor($class); | |
$rflClass = new \ReflectionClass($class); | |
$props = $rflClass->getProperties(); | |
foreach ($props as $prop) { | |
$doc = $prop->getDocComment(); | |
if (empty($doc)) { | |
continue; | |
} | |
// Format: @protobuf(tag=X, type=bool, required=true) | |
// Extract annotation from the comment | |
if (!preg_match('/@protobuf\s?\(([^\)]+)\)/', $doc, $m)) { | |
continue; | |
} | |
// Parse params | |
$params = explode(',', $m[1]); | |
$params = array_filter(array_map('trim', $params)); | |
$options = array(); | |
foreach ($params as $param) { | |
$parts = explode('=', $param); | |
$parts = array_filter(array_map('trim', $parts)); | |
$options[$parts[0]] = count($parts) < 2 | |
? true | |
: $parts[1]; | |
} | |
// Check if we have the minimum required options | |
if (empty($options['tag'])) { | |
throw new \InvalidArgumentException('The tag option is required for property ' . $prop->getName()); | |
} | |
if (empty($options['type'])) { | |
throw new \InvalidArgumentException('The type option is required for property ' . $prop->getName()); | |
} | |
// Normalize boolean values | |
foreach(array('required', 'optional', 'repeated', 'packed') as $opt) { | |
if (isset($options[$opt])) { | |
$options[$opt] = filter_var($options[$opt], FILTER_VALIDATE_BOOLEAN); | |
} | |
} | |
// Build a field descriptor | |
$f = new Protobuf\Field(); | |
$f->number = (int)$options['tag']; | |
$f->name = $prop->getName(); | |
// Convert type name to its numeric constant | |
switch (strtolower($options['type'])) { | |
case 'double' : $f->type = Protobuf::TYPE_DOUBLE; break; | |
case 'float' : $f->type = Protobuf::TYPE_FLOAT; break; | |
case 'int64' : $f->type = Protobuf::TYPE_INT64; break; | |
case 'uint64' : $f->type = Protobuf::TYPE_UINT64; break; | |
case 'int32' : $f->type = Protobuf::TYPE_INT32; break; | |
case 'fixed64' : $f->type = Protobuf::TYPE_FIXED64; break; | |
case 'fixed32' : $f->type = Protobuf::TYPE_FIXED32; break; | |
case 'bool' : $f->type = Protobuf::TYPE_BOOL; break; | |
case 'string' : $f->type = Protobuf::TYPE_STRING; break; | |
case 'message' : $f->type = Protobuf::TYPE_MESSAGE; break; | |
case 'bytes' : $f->type = Protobuf::TYPE_BYTES; break; | |
case 'uint32' : $f->type = Protobuf::TYPE_UINT32; break; | |
case 'enum' : $f->type = Protobuf::TYPE_ENUM; break; | |
case 'sfixed32': $f->type = Protobuf::TYPE_SFIXED32; break; | |
case 'sfixed64': $f->type = Protobuf::TYPE_SFIXED64; break; | |
case 'sint32' : $f->type = Protobuf::TYPE_SINT32; break; | |
case 'sint64' : $f->type = Protobuf::TYPE_SINT64; break; | |
default: | |
throw new \InvalidArgumentException('Type ' . $options['type'] . ' is not recognized as valid for property ' . $prop->getName()); | |
} | |
// Define the rule type | |
$f->rule = Protobuf::RULE_OPTIONAL; | |
if (!empty($options['required'])) $f->rule = Protobuf::RULE_REQUIRED; | |
if (!empty($options['repeated'])) $f->rule = Protobuf::RULE_REPEATED; | |
// Check if it's flagged as packed | |
if (isset($options['packed'])) { | |
$f->packed = $options['packed']; | |
} | |
// Get the reference | |
if (isset($options['reference'])) { | |
$f->reference = $options['reference']; | |
} else if ($f->type === Protobuf::TYPE_MESSAGE || $f->type === Protobuf::TYPE_ENUM) { | |
throw new \InvalidArgumentException('Property ' . $prop->getName() . ' requires the "reference" option'); | |
} | |
if (isset($options['default'])) { | |
$f->default = $options['default']; | |
} | |
// Add the field to the message descriptor | |
$descriptor->addField($f); | |
} | |
return $descriptor; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
class Binary implements Protobuf\CodecInterface | |
{ | |
const WIRE_VARINT = 0; | |
const WIRE_FIXED64 = 1; | |
const WIRE_LENGTH = 2; | |
const WIRE_GROUP_START = 3; | |
const WIRE_GROUP_END = 4; | |
const WIRE_FIXED32 = 5; | |
const WIRE_UNKNOWN = -1; | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @return string | |
*/ | |
public function encode(Protobuf\Message $message) | |
{ | |
return $this->encodeMessage($message); | |
} | |
/** | |
* @param String|Message $message | |
* @param String $data | |
* @return \DrSlump\Protobuf\Message | |
*/ | |
public function decode(Protobuf\Message $message, $data) | |
{ | |
return $this->decodeMessage($message, $data); | |
} | |
protected function encodeMessage(Protobuf\Message $message) | |
{ | |
$writer = new Binary\Writer(); | |
// Get message descriptor | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
foreach ($descriptor->getFields() as $tag=>$field) { | |
$empty = !$message->_has($tag); | |
if ($field->isRequired() && $empty) { | |
throw new \UnexpectedValueException( | |
'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value' | |
); | |
} | |
// Skip empty fields | |
if ($empty) { | |
continue; | |
} | |
$type = $field->getType(); | |
$wire = $field->isPacked() ? self::WIRE_LENGTH : $this->getWireType($type, null); | |
// Compute key with tag number and wire type | |
$key = $tag << 3 | $wire; | |
$value = $message->_get($tag); | |
if ($field->isRepeated()) { | |
// Packed fields are encoded as a length-delimited stream containing | |
// the concatenated encoding of each value. | |
if ($field->isPacked() && !empty($value)) { | |
$subwriter = new Binary\Writer(); | |
foreach($value as $val) { | |
$this->encodeSimpleType($subwriter, $type, $val); | |
} | |
$data = $subwriter->getBytes(); | |
$writer->varint($key); | |
$writer->varint(strlen($data)); | |
$writer->write($data); | |
} else { | |
foreach($value as $val) { | |
if ($type !== Protobuf::TYPE_MESSAGE) { | |
$writer->varint($key); | |
$this->encodeSimpleType($writer, $type, $val); | |
} else { | |
$writer->varint($key); | |
$data = $this->encodeMessage($val); | |
$writer->varint(strlen($data)); | |
$writer->write($data); | |
} | |
} | |
} | |
} else { | |
if ($type !== Protobuf::TYPE_MESSAGE) { | |
$writer->varint($key); | |
$this->encodeSimpleType($writer, $type, $value); | |
} else { | |
$writer->varint($key); | |
$data = $this->encodeMessage($value); | |
$writer->varint(strlen($data)); | |
$writer->write($data); | |
} | |
} | |
} | |
return $writer->getBytes(); | |
} | |
protected function encodeSimpleType($writer, $type, $value) | |
{ | |
switch ($type) { | |
case Protobuf::TYPE_INT32: | |
case Protobuf::TYPE_INT64: | |
case Protobuf::TYPE_UINT64: | |
case Protobuf::TYPE_UINT32: | |
$writer->varint($value); | |
break; | |
case Protobuf::TYPE_SINT32: // ZigZag | |
$writer->zigzag($value, 32); | |
break; | |
case Protobuf::TYPE_SINT64 : // ZigZag | |
$writer->zigzag($value, 64); | |
break; | |
case Protobuf::TYPE_DOUBLE: | |
$writer->double($value); | |
break; | |
case Protobuf::TYPE_FIXED64: | |
$writer->fixed64($value); | |
break; | |
case Protobuf::TYPE_SFIXED64: | |
$writer->sFixed64($value); | |
break; | |
case Protobuf::TYPE_FLOAT: | |
$writer->float($value); | |
break; | |
case Protobuf::TYPE_FIXED32: | |
$writer->fixed32($value); | |
break; | |
case Protobuf::TYPE_SFIXED32: | |
$writer->sFixed32($value); | |
break; | |
case Protobuf::TYPE_BOOL: | |
$writer->varint($value ? 1 : 0); | |
break; | |
case Protobuf::TYPE_STRING: | |
case Protobuf::TYPE_BYTES: | |
$writer->varint(strlen($value)); | |
$writer->write($value); | |
break; | |
case Protobuf::TYPE_MESSAGE: | |
// Messages are not supported in this method | |
return null; | |
case Protobuf::TYPE_ENUM: | |
$writer->varint($value); | |
break; | |
default: | |
throw new \Exception('Unknown field type ' . $type); | |
} | |
} | |
protected function decodeMessage(\DrSlump\Protobuf\Message $message, $data) | |
{ | |
/** @var $message \DrSlump\Protobuf\Message */ | |
/** @var $descriptor \DrSlump\Protobuf\Descriptor */ | |
// Create a binary reader for the data | |
$reader = new Protobuf\Codec\Binary\Reader($data); | |
// Get message descriptor | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
while (!$reader->eof()) { | |
// Get initial varint with tag number and wire type | |
$key = $reader->varint(); | |
if ($reader->eof()) break; | |
$wire = $key & 0x7; | |
$tag = $key >> 3; | |
// Find the matching field for the tag number | |
$field = $descriptor->getField($tag); | |
if (!$field) { | |
$data = $this->decodeUnknown($reader, $wire); | |
$unknown = new Binary\Unknown($tag, $wire, $data); | |
$message->addUnknown($unknown); | |
continue; | |
} | |
$type = $field->getType(); | |
// Check if we are dealing with a packed stream, we cannot rely on the packed | |
// flag of the message since we cannot be certain if the creator of the message | |
// was using it. | |
if ($wire === self::WIRE_LENGTH && $field->isRepeated() && $this->isPackable($type)) { | |
$length = $reader->varint(); | |
$until = $reader->pos() + $length; | |
while ($reader->pos() < $until) { | |
$item = $this->decodeSimpleType($reader, $type, self::WIRE_VARINT); | |
$message->_add($tag, $item); | |
} | |
} else { | |
// Assert wire and type match | |
$this->assertWireType($wire, $type); | |
// Check if it's a sub-message | |
if ($type === Protobuf::TYPE_MESSAGE) { | |
$submessage = $field->getReference(); | |
$submessage = new $submessage; | |
$length = $this->decodeSimpleType($reader, Protobuf::TYPE_INT64, self::WIRE_VARINT); | |
$data = $reader->read($length); | |
$value = $this->decodeMessage($submessage, $data); | |
} else { | |
$value = $this->decodeSimpleType($reader, $type, $wire); | |
} | |
// Support non-packed repeated fields | |
if ($field->isRepeated()) { | |
$message->_add($tag, $value); | |
} else { | |
$message->_set($tag, $value); | |
} | |
} | |
} | |
return $message; | |
} | |
protected function isPackable($type) | |
{ | |
static $packable = array( | |
Protobuf::TYPE_INT64, | |
Protobuf::TYPE_UINT64, | |
Protobuf::TYPE_INT32, | |
Protobuf::TYPE_UINT32, | |
Protobuf::TYPE_SINT32, | |
Protobuf::TYPE_SINT64, | |
Protobuf::TYPE_DOUBLE, | |
Protobuf::TYPE_FIXED64, | |
Protobuf::TYPE_SFIXED64, | |
Protobuf::TYPE_FLOAT, | |
Protobuf::TYPE_FIXED32, | |
Protobuf::TYPE_SFIXED32, | |
Protobuf::TYPE_BOOL, | |
Protobuf::TYPE_ENUM | |
); | |
return in_array($type, $packable); | |
} | |
protected function decodeUnknown($reader, $wire) | |
{ | |
switch ($wire) { | |
case self::WIRE_VARINT: | |
return $reader->varint(); | |
case self::WIRE_LENGTH: | |
$length = $reader->varint(); | |
return $reader->read($length); | |
case self::WIRE_FIXED32: | |
return $reader->fixed32(); | |
case self::WIRE_FIXED64: | |
return $reader->fixed64(); | |
case self::WIRE_GROUP_START: | |
case self::WIRE_GROUP_END: | |
throw new \RuntimeException('Groups are deprecated in Protocol Buffers and unsupported by this library'); | |
default: | |
throw new \RuntimeException('Unsupported wire type (' . $wire . ') while consuming unknown field'); | |
} | |
} | |
protected function assertWireType($wire, $type) | |
{ | |
$expected = $this->getWireType($type, $wire); | |
if ($wire !== $expected) { | |
throw new \RuntimeException("Expected wire type $expected but got $wire for type $type"); | |
} | |
} | |
protected function getWireType($type, $default) | |
{ | |
switch ($type) { | |
case Protobuf::TYPE_INT32: | |
case Protobuf::TYPE_INT64: | |
case Protobuf::TYPE_UINT32: | |
case Protobuf::TYPE_UINT64: | |
case Protobuf::TYPE_SINT32: | |
case Protobuf::TYPE_SINT64: | |
case Protobuf::TYPE_BOOL: | |
case Protobuf::TYPE_ENUM: | |
return self::WIRE_VARINT; | |
case Protobuf::TYPE_FIXED64: | |
case Protobuf::TYPE_SFIXED64: | |
case Protobuf::TYPE_DOUBLE: | |
return self::WIRE_FIXED64; | |
case Protobuf::TYPE_STRING: | |
case Protobuf::TYPE_BYTES: | |
case Protobuf::TYPE_MESSAGE: | |
return self::WIRE_LENGTH; | |
case Protobuf::TYPE_FIXED32: | |
case Protobuf::TYPE_SFIXED32: | |
case Protobuf::TYPE_FLOAT: | |
return self::WIRE_FIXED32; | |
default: | |
// Unknown fields just return the reported wire type | |
return $default; | |
} | |
} | |
protected function decodeSimpleType($reader, $type, $wireType) | |
{ | |
switch ($type) { | |
case Protobuf::TYPE_INT64: | |
case Protobuf::TYPE_UINT64: | |
case Protobuf::TYPE_INT32: | |
case Protobuf::TYPE_UINT32: | |
return $reader->varint(); | |
case Protobuf::TYPE_SINT32: // ZigZag | |
return $reader->zigzag(); | |
case Protobuf::TYPE_SINT64: // ZigZag | |
return $reader->zigzag(); | |
case Protobuf::TYPE_DOUBLE: | |
return $reader->double(); | |
case Protobuf::TYPE_FIXED64: | |
return $reader->fixed64(); | |
case Protobuf::TYPE_SFIXED64: | |
return $reader->sFixed64(); | |
case Protobuf::TYPE_FLOAT: | |
return $reader->float(); | |
case Protobuf::TYPE_FIXED32: | |
return $reader->fixed32(); | |
case Protobuf::TYPE_SFIXED32: | |
return $reader->sFixed32(); | |
case Protobuf::TYPE_BOOL: | |
return (bool)$reader->varint(); | |
case Protobuf::TYPE_STRING: | |
$length = $reader->varint(); | |
return $reader->read($length); | |
case Protobuf::TYPE_MESSAGE: | |
// Messages are not supported in this method | |
return null; | |
case Protobuf::TYPE_BYTES: | |
$length = $reader->varint(); | |
return $reader->read($length); | |
case Protobuf::TYPE_ENUM: | |
return $reader->varint(); | |
default: | |
// Unknown type, follow wire type rules | |
switch ($wireType) { | |
case self::WIRE_VARINT: | |
return $reader->varint(); | |
case self::WIRE_FIXED32: | |
return $reader->fixed32(); | |
case self::WIRE_FIXED64: | |
return $reader->fixed64(); | |
case self::WIRE_LENGTH: | |
$length = $reader->varint(); | |
return $reader->read($length); | |
case self::WIRE_GROUP_START: | |
case self::WIRE_GROUP_END: | |
throw new \RuntimeException('Group is deprecated and not supported'); | |
default: | |
throw new \RuntimeException('Unsupported wire type number ' . $wireType); | |
} | |
} | |
} | |
} |
<?php | |
namespace DrSlump\Protobuf\Codec\Binary; | |
/** | |
* Implements reading primitives for Protobuf binary streams | |
* | |
* Important: There are no checks in place for overflows, so you must | |
* be aware of PHP's integer and floating point limits. | |
* | |
* @note Protobuf uses little-endian order | |
*/ | |
class Reader | |
{ | |
/** @var resource */ | |
protected $_fd; | |
/** | |
* Create a new reader from a file descriptor or a string of bytes | |
* | |
* @param resource|string $fdOrString | |
*/ | |
public function __construct($fdOrString) | |
{ | |
if (is_resource($fdOrString)) { | |
$this->_fd = $fdOrString; | |
} else { | |
// @todo Could this be faster by using a custom String wrapper? | |
$this->_fd = fopen('data://text/plain,' . urlencode($fdOrString), 'rb'); | |
} | |
} | |
public function __destruct() | |
{ | |
fclose($this->_fd); | |
} | |
/** | |
* Obtain a number of bytes from the string | |
* | |
* @throws \RuntimeException | |
* @param int $length | |
* @return string | |
*/ | |
public function read($length) | |
{ | |
// Protect against 0 byte reads when an EOF | |
if ($length < 1) return ''; | |
$bytes = fread($this->_fd, $length); | |
if (FALSE === $bytes) { | |
throw new \RuntimeException('Failed to read ' . $length . ' bytes'); | |
} | |
return $bytes; | |
} | |
/** | |
* Check if we have reached the end of the stream | |
* | |
* @return bool | |
*/ | |
public function eof() | |
{ | |
return feof($this->_fd); | |
} | |
/** | |
* Obtain the current position in the stream | |
* | |
* @return int | |
*/ | |
public function pos() | |
{ | |
return ftell($this->_fd); | |
} | |
/** | |
* Obtain a byte | |
* | |
* @return int | |
*/ | |
public function byte() | |
{ | |
return ord($this->read(1)); | |
} | |
/** | |
* Decode a varint | |
* | |
* @return int | |
*/ | |
public function varint() | |
{ | |
$result = $shift = 0; | |
do { | |
$byte = $this->byte(); | |
$result |= ($byte & 0x7f) << $shift; | |
$shift += 7; | |
} while ($byte > 0x7f); | |
return $result; | |
} | |
/** | |
* Decodes a zigzag integer of the given bits | |
* | |
* @param int $bits - Either 32 or 64 | |
*/ | |
public function zigzag() | |
{ | |
$number = $this->varint(); | |
return ($number >> 1) ^ (-($number & 1)); | |
} | |
/** | |
* Decode a fixed 32bit integer with sign | |
* | |
* @return int | |
*/ | |
public function sFixed32() | |
{ | |
$bytes = $this->read(4); | |
if ($this->isBigEndian()) { | |
$bytes = strrev($bytes); | |
} | |
list(, $result) = unpack('l', $bytes); | |
return $result; | |
} | |
/** | |
* Decode a fixed 32bit integer without sign | |
* | |
* @return int | |
*/ | |
public function fixed32() | |
{ | |
$bytes = $this->read(4); | |
if (PHP_INT_SIZE < 8) { | |
list(, $lo, $hi) = unpack('v*', $bytes); | |
$result = $hi << 16 | $lo; | |
} else { | |
list(, $result) = unpack('V*', $bytes); | |
} | |
return $result; | |
} | |
/** | |
* Decode a fixed 62bit integer with sign | |
* | |
* @return int | |
*/ | |
public function sFixed64() | |
{ | |
$bytes = $this->read(8); | |
list(, $lo0, $lo1, $hi0, $hi1) = unpack('v*', $bytes); | |
return ($hi1 << 16 | $hi0) << 32 | ($lo1 << 16 | $lo0); | |
} | |
/** | |
* Decode a fixed 62bit integer without sign | |
* | |
* @return int | |
*/ | |
public function fixed64() | |
{ | |
return $this->sFixed64(); | |
} | |
/** | |
* Decode a 32bit float | |
* | |
* @return float | |
*/ | |
public function float() | |
{ | |
$bytes = $this->read(4); | |
if ($this->isBigEndian()) { | |
$bytes = strrev($bytes); | |
} | |
list(, $result) = unpack('f', $bytes); | |
return $result; | |
} | |
/** | |
* Decode a 64bit double | |
* | |
* @return float | |
*/ | |
public function double() | |
{ | |
$bytes = $this->read(8); | |
if ($this->isBigEndian()) { | |
$bytes = strrev($bytes); | |
} | |
list(, $result) = unpack('d', $bytes); | |
return $result; | |
} | |
/** | |
* Check if the current architecture is Big Endian | |
* | |
* @return bool | |
*/ | |
public function isBigEndian() | |
{ | |
static $endianness; | |
if (NULL === $endianness) { | |
list(,$result) = unpack('L', pack('V', 1)); | |
$endianness = $result !== 1; | |
} | |
return $endianness; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec\Binary; | |
class Unknown extends \DrSlump\Protobuf\Unknown | |
{ | |
public function __construct($tag, $type, $data) | |
{ | |
$this->tag = $tag; | |
$this->type = $type; | |
$this->data = $data; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec\Binary; | |
/** | |
* Implements writing primitives for Protobuf binary streams | |
* | |
* @note Protobuf uses little-endian order | |
*/ | |
class Writer | |
{ | |
/** @var resource */ | |
protected $_fd; | |
public function __construct() | |
{ | |
$this->_fd = fopen('php://memory', 'wb'); | |
} | |
public function __destruct() | |
{ | |
fclose($this->_fd); | |
} | |
/** | |
* Get the current bytes in the stream | |
* | |
* @return string | |
*/ | |
public function getBytes() | |
{ | |
fseek($this->_fd, 0, SEEK_SET); | |
return stream_get_contents($this->_fd); | |
} | |
/** | |
* Store the given bytes in the stream | |
* | |
* @throws \RuntimeException | |
* @param string $bytes | |
* @param int $length | |
*/ | |
public function write($bytes, $length = null) | |
{ | |
if ($length === NULL) { | |
$length = strlen($bytes); | |
} | |
$written = fwrite($this->_fd, $bytes, $length); | |
if ($written !== $length) { | |
throw new \RuntimeException('Failed to write ' . $length . ' bytes'); | |
} | |
} | |
/** | |
* Store a single byte | |
* | |
* @param int $value | |
*/ | |
public function byte($value) | |
{ | |
$this->write(chr($value), 1); | |
} | |
/** | |
* Store an integer encoded as varint | |
* | |
* @throws \OutOfBoundsException | |
* @param int $value | |
*/ | |
public function varint($value) | |
{ | |
// Small values do not need to be encoded | |
if ($value >= 0 && $value < 0x80) { | |
$this->byte($value); | |
return; | |
} | |
// Build an array of bytes with the encoded values | |
if ($value > 0) { | |
$values = array(); | |
while ($value > 0) { | |
$values[] = 0x80 | ($value & 0x7f); | |
$value = $value >> 7; | |
} | |
} else if (function_exists('gmp_init')) { | |
$value = PHP_INT_SIZE < 8 | |
? gmp_and($value, '0x0ffffffffffffffff') | |
: sprintf('%u', $value); | |
$values = $this->varint_gmp($value); | |
} else if (PHP_INT_SIZE < 8) { | |
throw new \OutOfBoundsException( | |
"PHP versions compiled with 32bit integers can only support negative integer encoding with GMP extension ($value was given)" | |
); | |
} else if (function_exists('bccomp')) { | |
$value = sprintf('%u', $value); | |
$values = $this->varint_bc($value); | |
} else { | |
throw new \OutOfBoundsException("Varints of negative integers are only supported with GMP or BC big integers PHP extensions ($value was given)"); | |
} | |
// Remove the MSB flag from the last byte | |
$values[count($values)-1] &= 0x7f; | |
// Convert the byte sized ints to actual bytes in a string | |
//$bytes = implode('', array_map('chr', $values)); | |
$bytes = call_user_func_array('pack', array_merge(array('C*'), $values));; | |
$this->write($bytes); | |
} | |
public function varint_gmp($value) | |
{ | |
static $x00, $x7f, $x80; | |
if (NULL === $x00) { | |
$x00 = \gmp_init(0x00); | |
$x7f = \gmp_init(0x7f); | |
$x80 = \gmp_init(0x80); | |
} | |
$values = array(); | |
while (\gmp_cmp($value, $x00) > 0) { | |
$values[] = \gmp_intval(\gmp_and($value, $x7f)) | 0x80; | |
$value = \gmp_div_q($value, $x80); | |
} | |
return $values; | |
} | |
public function varint_bc($value) | |
{ | |
$values = array(); | |
while (\bccomp($value, 0, 0) > 0) { | |
// Get the last 7bits of the number | |
$bin = ''; | |
$dec = $value; | |
do { | |
$rest = bcmod($dec, 2); | |
$dec = bcdiv($dec, 2, 0); | |
$bin = $rest . $bin; | |
} while ($dec > 0 && strlen($bin) < 7); | |
// Pack as a decimal and apply the flag | |
$values[] = intval($bin, 2) | 0x80; | |
$value = bcdiv($value, 0x80, 0); | |
} | |
return $values; | |
} | |
/** | |
* Encodes an integer with zigzag | |
* | |
* @param int $value | |
* @param int $base Either 32 or 64 bits | |
*/ | |
public function zigzag($value, $base = 32) | |
{ | |
$value = ($value << 1) ^ ($value >> $base-1); | |
$this->varint($value); | |
} | |
/** | |
* Encode an integer as a fixed of 32bits with sign | |
* | |
* @param int $value | |
*/ | |
public function sFixed32($value) | |
{ | |
$bytes = pack('l*', $value); | |
if ($this->isBigEndian()) { | |
$bytes = strrev($bytes); | |
} | |
$this->write($bytes, 4); | |
} | |
/** | |
* Encode an integer as a fixed of 32bits without sign | |
* | |
* @param int $value | |
*/ | |
public function fixed32($value) | |
{ | |
$bytes = pack('V*', $value); | |
$this->write($bytes, 4); | |
} | |
/** | |
* Encode an integer as a fixed of 64bits with sign | |
* | |
* @param int $value | |
*/ | |
public function sFixed64($value) | |
{ | |
if ($value >= 0) { | |
$this->fixed64($value); | |
} else if (function_exists('gmp_init')) { | |
$this->sFixed64_gmp($value); | |
} else if (function_exists('bcadd')) { | |
$this->sFixed64_bc($value); | |
} else { | |
throw new \OutOfBoundsException("The signed Fixed64 type with negative integers is only supported with GMP or BC big integers PHP extensions ($value was given)"); | |
} | |
} | |
public function sFixed64_gmp($value) | |
{ | |
static $xff, $x100; | |
if (NULL === $xff) { | |
$xff = gmp_init(0xff); | |
$x100 = gmp_init(0x100); | |
} | |
$value = PHP_INT_SIZE < 8 | |
? gmp_and($value, '0x0ffffffffffffffff') | |
: gmp_init(sprintf('%u', $value)); | |
$bytes = ''; | |
for ($i=0; $i<8; $i++) { | |
$bytes .= chr(gmp_intval(gmp_and($value, $xff))); | |
$value = gmp_div_q($value, $x100); | |
} | |
$this->write($bytes); | |
} | |
public function sFixed64_bc($value) | |
{ | |
if (PHP_INT_SIZE < 8) { | |
throw new \OutOfBoundsException( | |
"PHP versions compiled with 32bit integers can only support negative integer encoding with GMP extension ($value was given)" | |
); | |
} | |
$value = sprintf('%u', $value); | |
$bytes = ''; | |
for ($i=0; $i<8; $i++) { | |
// Get the last 8bits of the number | |
$bin = ''; | |
$dec = $value; | |
do { | |
$bin = bcmod($dec, 2) . $bin; | |
$dec = bcdiv($dec, 2, 0); | |
} while (strlen($bin) < 8); | |
// Pack the byte | |
$bytes .= chr(intval($bin, 2)); | |
$value = bcdiv($value, 0x100, 0); | |
} | |
$this->write($bytes); | |
} | |
/** | |
* Encode an integer as a fixed of 64bits without sign | |
* | |
* @param int $value | |
*/ | |
public function fixed64($value) | |
{ | |
$bytes = pack('V*', $value & 0xffffffff, $value / (0xffffffff+1)); | |
$this->write($bytes, 8); | |
} | |
/** | |
* Encode a number as a 32bit float | |
* | |
* @param float $value | |
*/ | |
public function float($value) | |
{ | |
$bytes = pack('f*', $value); | |
if ($this->isBigEndian()) { | |
$bytes = strrev($bytes); | |
} | |
$this->write($bytes, 4); | |
} | |
/** | |
* Encode a number as a 64bit double | |
* | |
* @param float $value | |
*/ | |
public function double($value) | |
{ | |
$bytes = pack('d*', $value); | |
if ($this->isBigEndian()) { | |
$bytes = strrev($bytes); | |
} | |
$this->write($bytes, 8); | |
} | |
/** | |
* Checks if the current architecture is Big Endian | |
* | |
* @return bool | |
*/ | |
public function isBigEndian() | |
{ | |
static $endianness; | |
if (NULL === $endianness) { | |
list(,$result) = unpack('L', pack('V', 1)); | |
$endianness = $result !== 1; | |
} | |
return $endianness; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
/** | |
* This codec serializes and unserializes from/to Json strings | |
* where the keys represent the field's name. | |
* | |
* It makes use of the PhpArray codec to do the heavy work to just | |
* take care of converting the array to/from Json strings. | |
*/ | |
class Json extends PhpArray | |
implements Protobuf\CodecInterface | |
{ | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @return string | |
*/ | |
public function encode(Protobuf\Message $message) | |
{ | |
$data = $this->encodeMessage($message); | |
return json_encode($data); | |
} | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @param string $data | |
* @return \DrSlump\Protobuf\Message | |
*/ | |
public function decode(Protobuf\Message $message, $data) | |
{ | |
$data = json_decode($data); | |
return $this->decodeMessage($message, $data); | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
/** | |
* This codec serializes and unserializes from/to Json strings | |
* where the keys are packed as the first element of numeric arrays, | |
* optimizing the resulting payload size. | |
* | |
*/ | |
class JsonIndexed extends Json | |
implements Protobuf\CodecInterface | |
{ | |
protected function encodeMessage(Protobuf\Message $message) | |
{ | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
$index = ''; | |
$data = array(); | |
foreach ($descriptor->getFields() as $tag=>$field) { | |
$empty = !$message->_has($tag); | |
if ($field->isRequired() && $empty) { | |
throw new \UnexpectedValueException( | |
'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value' | |
); | |
} | |
if ($empty) { | |
continue; | |
} | |
$index .= $this->i2c($tag + 48); | |
$value = $message->_get($tag); | |
if ($field->isRepeated()) { | |
$repeats = array(); | |
foreach ($value as $val) { | |
if ($field->getType() !== Protobuf::TYPE_MESSAGE) { | |
$repeats[] = $val; | |
} else { | |
$repeats[] = $this->encodeMessage($val); | |
} | |
} | |
$data[] = $repeats; | |
} else { | |
if ($field->getType() === Protobuf::TYPE_MESSAGE) { | |
$data[] = $this->encodeMessage($value); | |
} else { | |
$data[] = $value; | |
} | |
} | |
} | |
// Insert the index at first element | |
array_unshift($data, $index); | |
return $data; | |
} | |
protected function decodeMessage(Protobuf\Message $message, $data) | |
{ | |
// Get message descriptor | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
// Split the index in UTF8 characters | |
preg_match_all('/./u', $data[0], $chars); | |
$chars = $chars[0]; | |
for ($i=1; $i<count($data); $i++) { | |
$k = $this->c2i($chars[$i-1]) - 48; | |
$v = $data[$i]; | |
$field = $descriptor->getField($k); | |
if (NULL === $field) { | |
// Unknown | |
$unknown = new PhpArray\Unknown($k, gettype($v), $v); | |
$message->addUnknown($unknown); | |
continue; | |
} | |
if ($field->getType() === Protobuf::TYPE_MESSAGE) { | |
$nested = $field->getReference(); | |
if ($field->isRepeated()) { | |
foreach ($v as $vv) { | |
$obj = $this->decodeMessage(new $nested, $vv); | |
$message->_add($k, $obj); | |
} | |
} else { | |
$obj = $this->decodeMessage(new $nested, $v); | |
$message->_set($k, $obj); | |
} | |
} else { | |
$message->_set($k, $v); | |
} | |
} | |
return $message; | |
} | |
/** | |
* Converts an Unicode codepoint number to an UTF-8 character | |
* | |
* @param int $codepoint | |
* @return string | |
*/ | |
protected function i2c($codepoint) | |
{ | |
return $codepoint < 128 | |
? chr($codepoint) | |
: html_entity_decode("&#$codepoint;", ENT_NOQUOTES, 'UTF-8'); | |
} | |
/** | |
* Converts an UTF-8 character to an Unicode codepoint number | |
* | |
* @param string $char | |
* @return int | |
*/ | |
protected function c2i($char) | |
{ | |
$value = ord($char[0]); | |
if ($value < 128) return $value; | |
if ($value < 224) { | |
return (($value % 32) * 64) + (ord($char[1]) % 64); | |
} else { | |
return (($value % 16) * 4096) + | |
((ord($char[1]) % 64) * 64) + | |
(ord($char[2]) % 64); | |
} | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
/** | |
* This codec serializes and unserializes from/to Json strings | |
* where the keys represent the field's tag numbers. | |
* | |
* It makes use of the PhpArray codec to do the heavy work to just | |
* take care of converting the array to/from Json strings. | |
*/ | |
class JsonTagMap extends Json | |
implements Protobuf\CodecInterface | |
{ | |
public function __construct() | |
{ | |
// Setup the codec to use tag numbers as keys | |
$this->useTagNumberAsKey(true); | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
/** | |
* This codec serializes and unserializes data from/to PHP associative | |
* arrays, allowing it to be used as a base for an arbitrary number | |
* of different serializations (json, yaml, ini, xml ...). | |
* | |
*/ | |
class PhpArray implements Protobuf\CodecInterface | |
{ | |
/** @var bool */ | |
protected $useTagNumber = false; | |
/** | |
* Tells the codec to expect the array keys to contain the | |
* field's tag number instead of the name. | |
* | |
* @param bool $useIt | |
*/ | |
public function useTagNumberAsKey($useIt = true) | |
{ | |
$this->useTagNumber = $useIt; | |
} | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @return array | |
*/ | |
public function encode(Protobuf\Message $message) | |
{ | |
return $this->encodeMessage($message); | |
} | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @param array $data | |
* @return \DrSlump\Protobuf\Message | |
*/ | |
public function decode(Protobuf\Message $message, $data) | |
{ | |
return $this->decodeMessage($message, $data); | |
} | |
protected function encodeMessage(Protobuf\Message $message) | |
{ | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
$data = array(); | |
foreach ($descriptor->getFields() as $tag=>$field) { | |
$empty = !$message->_has($tag); | |
if ($field->isRequired() && $empty) { | |
throw new \UnexpectedValueException( | |
'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value' | |
); | |
} | |
if ($empty) { | |
continue; | |
} | |
$key = $this->useTagNumber ? $field->getNumber() : $field->getName(); | |
$v = $message->_get($tag); | |
if ($field->isRepeated()) { | |
// Make sure the value is an array of values | |
$v = is_array($v) ? $v : array($v); | |
foreach ($v as $k=>$vv) { | |
$v[$k] = $this->filterValue($vv, $field); | |
} | |
} else { | |
$v = $this->filterValue($v, $field); | |
} | |
$data[$key] = $v; | |
} | |
return $data; | |
} | |
protected function decodeMessage(Protobuf\Message $message, $data) | |
{ | |
// Get message descriptor | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
foreach ($data as $key=>$v) { | |
// Get the field by tag number or name | |
$field = $this->useTagNumber | |
? $descriptor->getField($key) | |
: $descriptor->getFieldByName($key); | |
// Unknown field found | |
if (!$field) { | |
$unknown = new PhpArray\Unknown($key, gettype($v), $v); | |
$message->addUnknown($unknown); | |
continue; | |
} | |
if ($field->isRepeated()) { | |
// Make sure the value is an array of values | |
$v = is_array($v) && is_int(key($v)) ? $v : array($v); | |
foreach ($v as $k=>$vv) { | |
$v[$k] = $this->filterValue($vv, $field); | |
} | |
} else { | |
$v = $this->filterValue($v, $field); | |
} | |
$message->_set($field->getNumber(), $v); | |
} | |
return $message; | |
} | |
protected function filterValue($value, Protobuf\Field $field) | |
{ | |
switch ($field->getType()) { | |
case Protobuf::TYPE_MESSAGE: | |
// Tell apart encoding and decoding | |
if ($value instanceof Protobuf\Message) { | |
return $this->encodeMessage($value); | |
} else { | |
$nested = $field->getReference(); | |
return $this->decodeMessage(new $nested, $value); | |
} | |
case Protobuf::TYPE_BOOL: | |
return filter_var($value, FILTER_VALIDATE_BOOLEAN); | |
case Protobuf::TYPE_STRING: | |
case Protobuf::TYPE_BYTES: | |
return (string)$value; | |
case Protobuf::TYPE_FLOAT: | |
case Protobuf::TYPE_DOUBLE: | |
return filter_var($value, FILTER_VALIDATE_FLOAT); | |
// Assume the rest are ints | |
default: | |
return filter_var($value, FILTER_VALIDATE_INT); | |
} | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec\PhpArray; | |
class Unknown extends \DrSlump\Protobuf\Unknown | |
{ | |
public function __construct($tag, $type, $data) | |
{ | |
$this->tag = $tag; | |
$this->type = $type; | |
$this->data = $data; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
/** | |
* This codec serializes to Protobuf's TextFormat, unserialization | |
* is not supported. | |
* | |
*/ | |
class TextFormat implements Protobuf\CodecInterface | |
{ | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @return string | |
*/ | |
public function encode(Protobuf\Message $message) | |
{ | |
return $this->encodeMessage($message); | |
} | |
/** | |
* | |
* @throw \DrSlump\Protobuf\Exception - Decoding is not supported | |
* @param \DrSlump\Protobuf\Message $message | |
* @param String $data | |
* @return \DrSlump\Protobuf\Message | |
*/ | |
public function decode(Protobuf\Message $message, $data) | |
{ | |
throw new \BadMethodCallException('TextFormat codec does not support decoding'); | |
} | |
protected function encodeMessage(Protobuf\Message $message, $level = 0) | |
{ | |
$descriptor = Protobuf::getRegistry()->getDescriptor($message); | |
$indent = str_repeat(' ', $level); | |
$data = ''; | |
foreach ($descriptor->getFields() as $tag=>$field) { | |
$empty = !$message->_has($tag); | |
if ($field->isRequired() && $empty) { | |
throw new \UnexpectedValueException( | |
'Message ' . get_class($message) . '\'s field tag ' . $tag . '(' . $field->getName() . ') is required but has no value' | |
); | |
} | |
if ($empty) { | |
continue; | |
} | |
$name = $field->getName(); | |
$value = $message->_get($tag); | |
if ($field->isRepeated()) { | |
foreach ($value as $val) { | |
if ($field->getType() !== Protobuf::TYPE_MESSAGE) { | |
$data .= $indent . $name . ': ' . json_encode($val) . "\n"; | |
} else { | |
$data .= $indent . $name . " {\n"; | |
$data .= $this->encodeMessage($val, $level+1); | |
$data .= $indent . "}\n"; | |
} | |
} | |
} else { | |
if ($field->getType() === Protobuf::TYPE_MESSAGE) { | |
$data .= $indent . $name . " {\n"; | |
$data .= $this->encodeMessage($value, $level+1); | |
$data .= $indent . "}\n"; | |
} else { | |
$data .= $indent . $name . ': ' . json_encode($value) . "\n"; | |
} | |
} | |
} | |
return $data; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Codec; | |
use DrSlump\Protobuf; | |
/** | |
* This codec serializes and unserializes from/to Xml documents | |
* where the elements represent the field's name. | |
* | |
* It makes use of the PhpArray codec to do the heavy work to just | |
* take care of converting the array to/from XML. | |
*/ | |
class Xml extends PhpArray | |
implements Protobuf\CodecInterface | |
{ | |
/** @var bool */ | |
protected $dom = false; | |
/** @var string */ | |
protected $root; | |
/** | |
* @param array $options | |
*/ | |
public function __construct(array $options = array()) | |
{ | |
foreach ($options as $option=>$value) { | |
$this->setOption($option, $value); | |
} | |
} | |
/** | |
* @throws \InvalidArgumentException | |
* @param string $option | |
* @param mixed $value | |
* @return void | |
*/ | |
public function setOption($option, $value) | |
{ | |
switch (strtolower($option)) { | |
case 'root': | |
$this->root = $value; | |
break; | |
case 'dom': | |
$this->dom = (bool)$value; | |
break; | |
default: | |
throw new \InvalidArgumentException('Unknown option ' . $option); | |
} | |
} | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @return string | \SimpleXMLElement | |
*/ | |
public function encode(Protobuf\Message $message) | |
{ | |
// Generate an associative array | |
$data = $this->encodeMessage($message); | |
// Build an XML representation | |
$root = $this->root ?: str_replace('\\', '_', get_class($message)); | |
$root = new \SimpleXMLElement('<?xml version="1.0"?><' . $root . '></' . $root . '>'); | |
$this->arrayToXml($root, $data); | |
return $this->dom ? $root : $root->asXML(); | |
} | |
/** | |
* @param \SimpleXMLElement $elem | |
* @param array $data | |
* @param null $label | |
*/ | |
protected function arrayToXml(\SimpleXMLElement $elem, array $data, $label = null) | |
{ | |
foreach ($data as $k=>$v) { | |
if (is_array($v)) { | |
// Detect nested messages | |
if (!is_int(key($v))) { | |
$child = $elem->addChild($label ?: $k); | |
$this->arrayToXml($child, $v); | |
// Lists are forced a fixed label | |
} else { | |
$this->arrayToXml($elem, $v, $k); | |
} | |
} else { | |
$elem->addChild($label ?: $k, $v); | |
} | |
} | |
} | |
/** | |
* @param \DrSlump\Protobuf\Message $message | |
* @param string | \SimpleXMLElement $xml | |
* @return \DrSlump\Protobuf\Message | |
*/ | |
public function decode(Protobuf\Message $message, $xml) | |
{ | |
if (is_string($xml)) { | |
$xml = new \SimpleXMLElement($xml); | |
} | |
// Build an associative array from the XML | |
$data = $this->xmlToArray($xml); | |
// Generate a message from the data | |
return $this->decodeMessage($message, $data); | |
} | |
/** | |
* @param \SimpleXMLElement $elem | |
* @return array | |
*/ | |
protected function xmlToArray(\SimpleXMLElement $elem) | |
{ | |
$data = array(); | |
foreach ($elem->children() as $child) { | |
if (count($child->children())) { | |
$value = $this->xmlToArray($child); | |
} else { | |
$value = (string)$child; | |
} | |
$name = $child->getName(); | |
if (isset($data[$name])) { | |
// If not yet a "list" array | |
if (!is_array($data[$name]) || !is_int(key($data[$name]))) { | |
$data[$name] = array($data[$name]); | |
} | |
$data[$name][] = $value; | |
} else { | |
$data[$name] = $value; | |
} | |
} | |
return $data; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf; | |
interface CodecInterface | |
{ | |
public function encode(\DrSlump\Protobuf\Message $message); | |
public function decode(\DrSlump\Protobuf\Message $message, $data); | |
} |
<?php | |
namespace DrSlump\Protobuf; | |
// Load descriptor messages | |
require_once __DIR__ . '/Compiler/protos/descriptor.pb.php'; | |
require_once __DIR__ . '/Compiler/protos/plugin.pb.php'; | |
require_once __DIR__ . '/Compiler/protos/php.pb.php'; | |
require_once __DIR__ . '/Compiler/protos/json.pb.php'; | |
use DrSlump\Protobuf; | |
use google\protobuf as proto; | |
class Compiler | |
{ | |
/** @var bool */ | |
protected $verbose = false; | |
/** @var array */ | |
protected $packages = array(); | |
/** @var \DrSlump\Protobuf\Compiler\CommentsParser */ | |
protected $comments; | |
/** @var bool */ | |
protected $skipImported = false; | |
/** @var array */ | |
protected $options = array(); | |
/** @var array */ | |
protected $protos = array(); | |
public function __construct($verbose = false) | |
{ | |
$this->verbose = $verbose; | |
$this->comments = new Compiler\CommentsParser(); | |
} | |
public function stderr($str) | |
{ | |
$str = str_replace("\n", PHP_EOL, $str); | |
fputs(STDERR, $str . PHP_EOL); | |
} | |
public function notice($str) | |
{ | |
if ($this->verbose) { | |
$this->stderr('NOTICE: ' . $str); | |
} | |
} | |
public function warning($str) | |
{ | |
$this->stderr('WARNING: ' . $str); | |
} | |
protected function error($str) | |
{ | |
$this->stderr('ERROR: ' . $str); | |
} | |
public function getPackages() | |
{ | |
return $this->packages; | |
} | |
public function hasPackage($package) | |
{ | |
return isset($this->packages[$package]); | |
} | |
public function getPackage($package) | |
{ | |
return $this->packages[$package]; | |
} | |
public function setPackage($package, $namespace) | |
{ | |
$this->packages[$package] = $namespace; | |
} | |
public function getOption($option, $type = 'string') | |
{ | |
$value = isset($this->options[$option]) | |
? $this->options[$option] | |
: null; | |
switch ($type) { | |
case 'bool': | |
return filter_var($value, FILTER_VALIDATE_BOOLEAN); | |
default: | |
return $value; | |
} | |
} | |
public function camelize($name) | |
{ | |
return preg_replace_callback( | |
'/_([a-z])/i', | |
function($m){ return strtoupper($m[1]); }, | |
$name | |
); | |
} | |
public function compile($data) | |
{ | |
// Parse the request | |
$req = new \google\protobuf\compiler\CodeGeneratorRequest($data); | |
// Set default generator class | |
$generator = __CLASS__ . '\PhpGenerator'; | |
// Reset comments parser | |
$this->comments->reset(); | |
$parseComments = false; | |
// Get plugin arguments | |
if ($req->hasParameter()) { | |
parse_str($req->getParameter(), $args); | |
foreach ($args as $arg=>$val) { | |
switch($arg){ | |
case 'verbose': | |
$this->verbose = filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); | |
break; | |
case 'json': | |
$this->notice("Using ProtoJson generator"); | |
$generator = __CLASS__ . '\JsonGenerator'; | |
break; | |
case 'comments': | |
$parseComments = filter_var($val, FILTER_VALIDATE_BOOLEAN); | |
break; | |
case 'protos': | |
$this->protos = $val; | |
break; | |
case 'skip-imported': | |
$this->skipImported = filter_var($val, FILTER_VALIDATE_BOOLEAN); | |
break; | |
case 'options': | |
$this->options = $val; | |
break; | |
default: | |
$this->warning('Skipping unknown option ' . $arg); | |
} | |
} | |
} | |
// Parse comments if we're told to do so | |
if ($parseComments) { | |
if (empty($this->protos)) { | |
throw new \RuntimeException('Unable to port comments if .proto files are not passed as argument'); | |
} | |
foreach ($this->protos as $fname) { | |
$src = file_get_contents($fname); | |
if (FALSE === $src) { | |
throw new \RuntimeException('Unable to parse file ' . $fname . ' for comments'); | |
} | |
$this->comments->parse($src); | |
} | |
} | |
/** @var $generator \DrSlump\Protobuf\Compiler\AbstractGenerator */ | |
$generator = new $generator($this); | |
// Setup response object | |
$resp = new \google\protobuf\compiler\CodeGeneratorResponse(); | |
// First iterate over all the protos to get a map of namespaces | |
$this->packages = array(); | |
foreach($req->getProtoFileList() as $proto) { | |
$package = $proto->getPackage(); | |
$namespace = $generator->getNamespace($proto); | |
if (isset($this->packages[$package]) && $namespace !== $this->packages[$package]) { | |
$this->warning("Package $package was already mapped to {$this->packages[$package]} but has now been overridden to $namespace"); | |
} | |
$this->packages[$package] = $namespace; | |
$this->notice("Mapping $package to $namespace"); | |
} | |
// Get the list of files to generate | |
$files = $req->getFileToGenerate(); | |
// Run each file | |
foreach ($req->getProtoFileList() as $file) { | |
// Only compile those given to generate, not the imported ones | |
if ($this->skipImported && !in_array($file->getName(), $files)) { | |
$this->notice('Skipping generation of imported file "' . $file->getName() . '"'); | |
continue; | |
} | |
$sources = $generator->generate($file); | |
foreach ($sources as $source) { | |
$this->notice('Generating "' . $source->getName() . '"'); | |
$resp->addFile($source); | |
} | |
} | |
// Finally serialize the response object | |
return $resp->serialize(); | |
} | |
public function getComment($ident, $prefix = '') | |
{ | |
if (!$this->comments->hasComment($ident)) { | |
return null; | |
} | |
$comment = $this->comments->getComment($ident); | |
if (0 < strlen($prefix)) { | |
$comment = $prefix . str_replace("\n", "\n$prefix", $comment); | |
} | |
return $comment; | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Compiler; | |
use google\protobuf as proto; | |
abstract class AbstractGenerator | |
{ | |
/** @var \DrSlump\Protobuf\Compiler */ | |
protected $compiler; | |
/** @var \google\protobuf\FileDescriptorProto */ | |
protected $proto; | |
/** @var array */ | |
protected $extensions = array(); | |
public function __construct(\DrSlump\Protobuf\Compiler $compiler) | |
{ | |
$this->compiler = $compiler; | |
} | |
public function getNamespace(proto\FileDescriptorProto $proto = NULL) | |
{ | |
return NULL === $proto | |
? $this->proto->getPackage() | |
: $proto->getPackage(); | |
} | |
public function generate(proto\FileDescriptorProto $proto) | |
{ | |
$this->proto = $proto; | |
} | |
abstract protected function compileEnum(proto\EnumDescriptorProto $enum, $namespace); | |
abstract protected function compileMessage(proto\DescriptorProto $msg, $namespace); | |
abstract protected function compileExtension(proto\FieldDescriptorProto $field, $ns, $indent); | |
} | |
<?php | |
namespace DrSlump\Protobuf\Compiler; | |
require_once 'Console/CommandLine.php'; | |
use DrSlump\Protobuf; | |
class Cli | |
{ | |
public static function run($pluginExecutable) | |
{ | |
// Open STDIN in non-blocking mode | |
$fp = fopen('php://stdin', 'rb'); | |
stream_set_blocking($fp, FALSE); | |
// Loop until STDIN is closed or we've waited too long for data | |
$cnt = 0; | |
$stdin = ''; | |
while (!feof($fp) && $cnt++ < 10) { | |
// give protoc some time to feed the data | |
usleep(10000); | |
// read the bytes | |
$bytes = fread($fp, 1024); | |
if (strlen($bytes)) { | |
$cnt = 0; | |
$stdin .= $bytes; | |
} | |
} | |
// If no input was given we launch protoc from here | |
if (0 === strlen($stdin)) { | |
self::runProtoc($pluginExecutable); | |
exit(0); | |
} | |
// We have data from stdin so compile it | |
try { | |
// Create a compiler interface | |
$comp = new Protobuf\Compiler(); | |
echo $comp->compile($stdin); | |
exit(0); | |
} catch(\Exception $e) { | |
fputs(STDERR, 'ERROR: ' . $e->getMessage()); | |
fputs(STDERR, $e->getTraceAsString()); | |
exit(255); | |
} | |
} | |
public static function runProtoc($pluginExecutable) | |
{ | |
$result = self::parseArguments(); | |
$protocBin = $result->options['protoc']; | |
// Check if protoc is available | |
exec("$protocBin --version", $output, $return); | |
if (0 !== $return && 1 !== $return) { | |
fputs(STDERR, "ERROR: Unable to find the protoc command.". PHP_EOL); | |
fputs(STDERR, " Please make sure it's installed and available in the path." . PHP_EOL); | |
exit(1); | |
} | |
if (!preg_match('/[0-9\.]+/', $output[0], $m)) { | |
fputs(STDERR, "ERROR: Unable to get protoc command version.". PHP_EOL); | |
fputs(STDERR, " Please make sure it's installed and available in the path." . PHP_EOL); | |
exit(1); | |
} | |
if (version_compare($m[0], '2.3.0') < 0) { | |
fputs(STDERR, "ERROR: The protoc command in your system is too old." . PHP_EOL); | |
fputs(STDERR, " Minimum version required is 2.3.0 but found {$m[0]}." . PHP_EOL); | |
exit(1); | |
} | |
$cmd[] = $protocBin; | |
$cmd[] = '--plugin=protoc-gen-php=' . escapeshellarg($pluginExecutable); | |
// Include paths | |
$cmd[] = '--proto_path=' . escapeshellarg(__DIR__ . DIRECTORY_SEPARATOR . 'protos'); | |
if (!empty($result->options['include'])) { | |
foreach($result->options['include'] as $include) { | |
$include = realpath($include); | |
$cmd[] = '--proto_path=' . escapeshellarg($include); | |
} | |
} | |
// Convert proto files to absolute paths | |
$protos = array(); | |
foreach ($result->args['protos'] as $proto) { | |
$realpath = realpath($proto); | |
if (FALSE === $realpath) { | |
fputs(STDERR, "ERROR: File '$proto' does not exists"); | |
exit(1); | |
} | |
$protos[] = $realpath; | |
} | |
// Protoc will pass custom arguments to the plugin if they are given | |
// before a colon character. ie: --php_out="foo=bar:/path/to/plugin" | |
// We make use of it to pass arguments encoded as an URI query string | |
$args = array(); | |
if ($result->options['comments']) { | |
$args['comments'] = 1; | |
// Protos are only needed for comments right now | |
$args['protos'] = $protos; | |
} | |
if ($result->options['verbose']) { | |
$args['verbose'] = 1; | |
} | |
if ($result->options['json']) { | |
$args['json'] = 1; | |
} | |
if ($result->options['skipImported']) { | |
$args['skip-imported'] = 1; | |
} | |
if ($result->options['define']) { | |
$args['options'] = array(); | |
foreach($result->options['define'] as $define) { | |
$parts = explode('=', $define); | |
$parts = array_filter(array_map('trim', $parts)); | |
if (count($parts) === 1) { | |
$parts[1] = 1; | |
} | |
$args['options'][$parts[0]] = $parts[1]; | |
} | |
} | |
$cmd[] = '--php_out=' . | |
escapeshellarg( | |
http_build_query($args, '', '&') . | |
':' . | |
$result->options['out'] | |
); | |
// Add the chosen proto files to generate | |
foreach ($protos as $proto) { | |
$cmd[] = escapeshellarg($proto); | |
} | |
$cmdStr = implode(' ', $cmd); | |
// Run command with stderr redirected to stdout | |
passthru($cmdStr . ' 2>&1', $return); | |
if ($return !== 0) { | |
fputs(STDERR, PHP_EOL); | |
fputs(STDERR, 'ERROR: protoc exited with an error (' . $return . ') when executed with: ' . PHP_EOL); | |
fputs(STDERR, ' ' . implode(" \\\n ", $cmd) . PHP_EOL); | |
exit($return); | |
} | |
} | |
public static function parseArguments() | |
{ | |
$main = new \Console_CommandLine(); | |
$main->addOption('out', array( | |
'short_name' => '-o', | |
'long_name' => '--out', | |
'action' => 'StoreString', | |
'description' => 'destination directory for generated files', | |
'default' => './', | |
)); | |
$main->addOption('include', array( | |
'short_name' => '-i', | |
'long_name' => '--include', | |
'action' => 'StoreArray', | |
'description' => 'define an include path (can be repeated)', | |
'multiple' => true, | |
)); | |
$main->addOption('json', array( | |
'short_name' => '-j', | |
'long_name' => '--json', | |
'action' => 'StoreTrue', | |
'description' => 'turn on ProtoJson Javascript file generation', | |
)); | |
$main->addOption('protoc', array( | |
'long_name' => '--protoc', | |
'action' => 'StoreString', | |
'default' => 'protoc', | |
'description' => 'protoc compiler executable path', | |
)); | |
$main->addOption('skipImported', array( | |
'long_name' => '--skip-imported', | |
'action' => 'StoreTrue', | |
'default' => false, | |
'description' => 'do not generate imported proto files', | |
)); | |
$main->addOption('comments', array( | |
'long_name' => '--comments', | |
'action' => 'StoreTrue', | |
'description' => 'port .proto comments to generated code', | |
)); | |
$main->addOption('define', array( | |
'short_name' => '-D', | |
'long_name' => '--define', | |
'action' => 'StoreArray', | |
'multiple' => true, | |
'description' => 'define a generator option (ie: -Dmultifile -Dsuffix=pb.php)', | |
)); | |
$main->addOption('verbose', array( | |
'short_name' => '-v', | |
'long_name' => '--verbose', | |
'action' => 'StoreTrue', | |
'description' => 'turn on verbose output', | |
)); | |
$main->addArgument('protos', array( | |
'multiple' => true, | |
'description' => 'proto files', | |
)); | |
try { | |
echo 'Protobuf-PHP ' . Protobuf::VERSION . ' by Ivan -DrSlump- Montes' . PHP_EOL . PHP_EOL; | |
$result = $main->parse(); | |
return $result; | |
} catch (\Exception $e) { | |
$main->displayError($e->getMessage()); | |
exit(1); | |
} | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Compiler; | |
class CommentsParser | |
{ | |
/** @var array - Hold a mapping of entity => comment */ | |
protected $comments = array(); | |
/** @var array - Define tokenizer regular expressions */ | |
protected $tokens = array( | |
'comment' => '/\*([\S\s]+?)\*/', | |
'package' => 'package\s+([A-Z0-9_]+)', | |
'struct' => '(?:message|enum|service)\s+([A-Z0-9_]+)', | |
'close' => '}', | |
'field' => '(?:required|optional|repeated)\s+[^=]+=\s*([0-9]+)[^;]*;', | |
'rpc' => 'rpc\s+([A-Z0-9_]+)[^;]+' | |
); | |
/** @var string - The regular expresion for the tokenizer */ | |
protected $regexp; | |
public function __construct() | |
{ | |
// Generate a regular expression for all tokens | |
$regexp = array(); | |
foreach ($this->tokens as $token=>$exp) { | |
$regexp[] = '(?<' . $token . '>' . $exp . ')'; | |
} | |
$this->regexp = '@' . implode('|', $regexp) . '@i'; | |
} | |
/** | |
* Reset the currently stored comments | |
*/ | |
public function reset() | |
{ | |
$this->comments = array(); | |
} | |
/** | |
* Parse a Proto file source code to fetch comments | |
* | |
* @param string $src | |
*/ | |
public function parse($src) | |
{ | |
// Build an stream of tokens from the regular expression | |
$tokens = array(); | |
$offset = 0; | |
while (preg_match($this->regexp, $src, $m, PREG_OFFSET_CAPTURE, $offset)) { | |
foreach ($this->tokens as $k=>$v) { | |
if (!empty($m[$k]) && 0 < strlen($m[$k][0])) { | |
$tokens[] = array( | |
'token' => $k, | |
'value' => array_shift(array_pop($m)), | |
); | |
} | |
} | |
$offset = $m[0][1] + strlen($m[0][0]); | |
} | |
// Parse the tokens stream to assign comments | |
$comment = null; | |
$stack = array(); | |
foreach ($tokens as $token) { | |
if ($token['token'] === 'comment') { | |
$comment = $token['value']; | |
} elseif ($token['token'] === 'package') { | |
$stack[] = $token['value']; | |
$comment = null; | |
} elseif ($token['token'] === 'struct') { | |
$stack[] = $token['value']; | |
if ($comment) { | |
$this->setComment(implode('.', $stack), $comment); | |
$comment = null; | |
} | |
} elseif ($token['token'] === 'close') { | |
array_pop($stack); | |
$comment = null; | |
} elseif ($token['token'] === 'field' || $token['token'] === 'rpc') { | |
if ($comment) { | |
$this->setComment(implode('.', $stack) . '.' . $token['value'], $comment); | |
$comment = null; | |
} | |
} | |
} | |
} | |
/** | |
* Set a comment for the given identifier. The identifier is composed | |
* of the package, followed by the message (and nested messages). Field | |
* comments are suffixed with the tag number. | |
* | |
* @example | |
* | |
* $this->setComment('MyPackage.MyMessage.Nested.2', 'field comment'); | |
* | |
* @param string $ident | |
* @param string $comment | |
*/ | |
public function setComment($ident, $comment) | |
{ | |
$comment = str_replace("\r\n", "\n", $comment); | |
$comment = preg_replace('/^[\s\*]+/m', '', $comment); | |
$comment = trim($comment, "* \n"); | |
$this->comments[$ident] = $comment; | |
} | |
/** | |
* Get the comment for a given identifier | |
* | |
* @param string $ident | |
* @return string|null | |
*/ | |
public function getComment($ident) | |
{ | |
return isset($this->comments[$ident]) | |
? $this->comments[$ident] | |
: null; | |
} | |
/** | |
* Checks if a comment exists for a given identifier | |
* | |
* @param string $ident | |
* @return bool | |
*/ | |
public function hasComment($ident) | |
{ | |
return isset($this->comments[$ident]); | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf\Compiler; | |
use DrSlump\Protobuf; | |
use google\protobuf as proto; | |
class JsonGenerator extends AbstractGenerator | |
{ | |
public function getNamespace(proto\FileDescriptorProto $proto) | |
{ | |
$namespace = $proto->getPackage(); | |
$opts = $proto->getOptions(); | |
if (isset($opts['json.package'])) { | |
$namespace = $opts['jsonpackage']; | |
} | |
if (isset($opts['json.namespace'])) { | |
$namespace = $opts['json.namespace']; | |
} | |
$namespace = trim($namespace, '.'); | |
return $namespace; | |
} | |
public function compileEnum(proto\EnumDescriptorProto $enum, $namespace) | |
{ | |
$s[]= "$namespace.$enum->name = {"; | |
$lines = array(); | |
foreach ($enum->getValueList() as $value) { | |
$lines[] = " /** @const */ $value->name: $value->number"; | |
} | |
$s[]= implode(",\n", $lines); | |
$s[]= '};'; | |
$s[]= ''; | |
return implode("\n", $s); | |
} | |
public function compileExtension(proto\FieldDescriptorProto $field, $ns, $indent) | |
{ | |
$extendee = $this->normalizeReference($field->getExtendee()); | |
$name = $field->getName(); | |
if ($ns) { | |
$name = $ns . '.' . $name; | |
} | |
$field->setName($name); | |
$s[]= "ProtoJson.extend($extendee, {"; | |
$s[]= " $field->number: " . $this->generateField($field); | |
$s[]= "});"; | |
$s[]= ''; | |
return $indent . implode("\n$indent", $s); | |
} | |
public function compileMessage(proto\DescriptorProto $msg, $namespace) | |
{ | |
$s[]= "/**"; | |
$s[]= " * @constructor"; | |
$s[]= " * @augments {ProtoJson.Message}"; | |
$s[]= " * @extends ProtoJson.Message"; | |
$s[]= " * @memberOf $namespace"; | |
$s[]= " * @param {object} data - Optional, provide initial data to parse"; | |
$s[]= " */"; | |
$s[]= "$namespace.$msg->name = ProtoJson.create({"; | |
$s[]= " fields: {"; | |
$lines = array(); | |
foreach ($msg->getFieldList() as $field) { | |
$lines[] = " $field->number: " . $this->generateField($field); | |
} | |
$s[] = implode(",\n", $lines); | |
$s[]= " },"; | |
$s[]= " ranges: ["; | |
// @todo dump extension ranges | |
$s[]= " ]"; | |
$s[]= "});"; | |
$s[]= ""; | |
// Compute a new namespace with the message name as suffix | |
$namespace .= "." . $msg->getName(); | |
// Generate getters/setters | |
foreach ($msg->getFieldList() as $field) { | |
$s[]= $this->generateAccessors($field, $namespace); | |
} | |
// Generate Enums | |
foreach ($msg->getEnumTypeList() as $enum): | |
$s[]= $this->compileEnum($enum, $namespace); | |
endforeach; | |
// Generate nested messages | |
foreach ($msg->getNestedTypeList() as $msg): | |
$s[]= $this->compileMessage($msg, $namespace); | |
endforeach; | |
// Collect extensions | |
foreach ($msg->getExtensionList() as $field) { | |
$this->extensions[$field->getExtendee()][] = array($namespace, $field); | |
} | |
return implode("\n", $s); | |
} | |
public function compileProtoFile(proto\FileDescriptorProto $proto) | |
{ | |
$file = new proto\compiler\CodeGeneratorResponse\File(); | |
$opts = $proto->getOptions(); | |
$name = pathinfo($proto->getName(), PATHINFO_FILENAME); | |
$name .= isset($opts['json.suffix']) | |
? $opts['json.suffix'] | |
: '.js'; | |
$file->setName($name); | |
$namespace = $this->getNamespace($proto); | |
$s[]= "// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin " . Protobuf::VERSION; | |
$s[]= "// Source: " . $proto->getName(); | |
$s[]= "// Date: " . date('Y-m-d H:i:s'); | |
$s[]= ""; | |
$s[]= "(function(){"; | |
$s[]= "/** @namespace */"; | |
$s[]= "var $namespace = $namespace || {};"; | |
$s[]= ""; | |
$s[]= "// Make it CommonJS compatible"; | |
$s[]= "if (typeof exports !== 'undefined') {"; | |
$s[]= " var ProtoJson = this.ProtoJson;"; | |
$s[]= " if (!ProtoJson && typeof require !== 'undefined')"; | |
$s[]= " ProtoJson = require('ProtoJson');"; | |
$s[]= " $namespace = exports;"; | |
$s[]= "} else {"; | |
$s[]= " this.$namespace = $namespace;"; | |
$s[]= "}"; | |
$s[]= ""; | |
// Generate Enums | |
foreach ($proto->getEnumTypeList() as $enum) { | |
$s[]= $this->compileEnum($enum, $namespace); | |
} | |
// Generate Messages | |
foreach ($proto->getMessageTypeList() as $msg) { | |
$s[] = $this->compileMessage($msg, $namespace); | |
} | |
// Collect extensions | |
if ($proto->hasExtension()) { | |
foreach ($proto->getExtensionList() as $field) { | |
$this->extensions[$field->getExtendee()][] = array($namespace, $field); | |
} | |
} | |
// Dump all extensions found in this proto file | |
if (count($this->extensions)) { | |
foreach ($this->extensions as $extendee => $fields) { | |
foreach ($fields as $pair) { | |
list($ns, $field) = $pair; | |
$s[]= $this->compileExtension($field, $ns, ''); | |
} | |
} | |
} | |
$s[]= "})();"; | |
$src = implode("\n", $s); | |
$file->setContent($src); | |
return array($file); | |
} | |
public function generateField(proto\FieldDescriptorProto $field) | |
{ | |
$reference = 'null'; | |
if ($field->hasTypeName()) { | |
$reference = $field->getTypeName(); | |
if (substr($reference, 0, 1) !== '.') { | |
throw new \RuntimeException('Only fully qualified names are supported: ' . $reference); | |
} | |
$reference = "'" . $this->normalizeReference($reference) . "'"; | |
} | |
$default = 'null'; | |
if ($field->hasDefaultValue()): | |
switch ($field->getType()) { | |
case Protobuf::TYPE_BOOL: | |
$default = $field->getDefaultValue() ? 'true' : 'false'; | |
break; | |
case Protobuf::TYPE_STRING: | |
$default = '"' . addcslashes($field->getDefaultValue(), '"\\') . '"'; | |
break; | |
case Protobuf::TYPE_ENUM: | |
$default = $this->normalizeReference($field->getTypeName()) . '.' . $field->getDefaultValue(); | |
break; | |
default: // Numbers | |
$default = $field->getDefaultValue(); | |
} | |
endif; | |
$data = array( | |
"'" . $field->getName() . "'", | |
$field->getLabel(), | |
$field->getType(), | |
$reference, | |
$default, | |
'{}' | |
); | |
return '[' . implode(', ', $data) . ']'; | |
} | |
public function generateAccessors($field, $namespace) | |
{ | |
$camel = $this->comp->camelize(ucfirst($field->getName())); | |
$s[]= "/**"; | |
$s[]= " * Check <$field->name> value"; | |
$s[]= " * @return {Boolean}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.has$camel = function(){"; | |
$s[]= " return this._has($field->number);"; | |
$s[]= "};"; | |
$s[]= ""; | |
$s[]= "/**"; | |
$s[]= " * Set a value for <$field->name>"; | |
$s[]= " * @param {" . $this->getJsDoc($field) . "} value"; | |
$s[]= " * @return {". $namespace . "}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.set$camel = function(value){"; | |
$s[]= " return this._set($field->number, value);"; | |
$s[]= "};"; | |
$s[]= ""; | |
$s[]= "/**"; | |
$s[]= " * Clear the value of <$field->name>"; | |
$s[]= " * @return {". $namespace . "}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.clear$camel = function(){"; | |
$s[]= " return this._clear($field->number);"; | |
$s[]= "};"; | |
$s[]= ""; | |
if ($field->getLabel() !== Protobuf::RULE_REPEATED): | |
$s[]= "/**"; | |
$s[]= " * Get <$field->name> value"; | |
$s[]= " * @return {" . $this->getJsDoc($field) . "}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.get$camel = function(){"; | |
$s[]= " return this._get($field->number);"; | |
$s[]= "};"; | |
$s[]= ""; | |
else: | |
$s[]= "/**"; | |
$s[]= " * Get an item from <$field->name>"; | |
$s[]= " * @param {int} idx"; | |
$s[]= " * @return {" . $this->getJsDoc($field) . "}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.get$camel = function(idx){"; | |
$s[]= " return this._get($field->number, idx);"; | |
$s[]= "};"; | |
$s[]= ""; | |
$s[]= "/**"; | |
$s[]= " * Get <$field->name> value"; | |
$s[]= " * @return {" . $this->getJsDoc($field) . "[]}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.get{$camel}List = function(){"; | |
$s[]= " return this._get($field->number);"; | |
$s[]= "};"; | |
$s[]= ""; | |
$s[]= "/**"; | |
$s[]= " * Add a value to <$field->name>"; | |
$s[]= " * @param {" . $this->getJsDoc($field) . "} value"; | |
$s[]= " * @return {" . $namespace . "}"; | |
$s[]= " */"; | |
$s[]= "$namespace.prototype.add$camel = function(value){"; | |
$s[]= " return this._add($field->number, value);"; | |
$s[]= "};"; | |
$s[]= ""; | |
endif; | |
return implode("\n", $s); | |
} | |
public function getJsDoc(proto\FieldDescriptorProto $field) | |
{ | |
switch ($field->getType()) { | |
case Protobuf::TYPE_DOUBLE: | |
case Protobuf::TYPE_FLOAT: | |
return 'Float'; | |
case Protobuf::TYPE_INT64: | |
case Protobuf::TYPE_UINT64: | |
case Protobuf::TYPE_INT32: | |
case Protobuf::TYPE_FIXED64: | |
case Protobuf::TYPE_FIXED32: | |
case Protobuf::TYPE_UINT32: | |
case Protobuf::TYPE_SFIXED32: | |
case Protobuf::TYPE_SFIXED64: | |
case Protobuf::TYPE_SINT32: | |
case Protobuf::TYPE_SINT64: | |
return 'Int'; | |
case Protobuf::TYPE_BOOL: | |
return 'Boolean'; | |
case Protobuf::TYPE_STRING: | |
return 'String'; | |
case Protobuf::TYPE_MESSAGE: | |
return $this->normalizeReference($field->getTypeName()); | |
case Protobuf::TYPE_BYTES: | |
return 'String'; | |
case Protobuf::TYPE_ENUM: | |
return 'Int (' . $this->normalizeReference($field->getTypeName()) . ')'; | |
case Protobuf::TYPE_GROUP: | |
default: | |
return 'unknown'; | |
} | |
} | |
public function normalizeReference($reference) | |
{ | |
// Remove leading dot | |
$reference = ltrim($reference, '.'); | |
if (!$this->comp->hasPackage($reference)) { | |
$found = false; | |
foreach ($this->comp->getPackages() as $package=>$namespace) { | |
if (0 === strpos($reference, $package.'.')) { | |
$reference = $namespace . substr($reference, strlen($package)); | |
$found = true; | |
} | |
} | |
if (!$found) { | |
$this->comp->warning('Non tracked package name found "' . $reference . '"'); | |
} | |
} else { | |
$reference = $this->comp->getPackage($reference); | |
} | |
return $reference; | |
} | |
} |
<?php | |
namespace DrSlump\Protobuf\Compiler; | |
use DrSlump\Protobuf; | |
use google\protobuf as proto; | |
class PhpGenerator extends AbstractGenerator | |
{ | |
protected $components = array(); | |
protected function addComponent($ns, $name, $src) | |
{ | |
if (NULL !== $ns) { | |
$name = $this->normalizeNS($ns . '.' . $name); | |
} | |
$this->components[$name] = $src; | |
} | |
/** | |
* Get an option from the compiler arguments or from the proto file. | |
* | |
* @param string $name | |
* @return string|null | |
*/ | |
protected function getOption($name) | |
{ | |
$opt = $this->compiler->getOption($name); | |
if (NULL === $opt) { | |
$opts = $this->proto->getOptions(); | |
if (!empty($opts) && isset($opts['php.' . $name])) { | |
$opt = $opts['php.' . $name]; | |
} | |
} | |
return $opt; | |
} | |
public function getNamespace(proto\FileDescriptorProto $proto = NULL) | |
{ | |
$proto = $proto ?: $this->proto; | |
$opts = $proto->getOptions(); | |
if ($this->compiler->getOption('namespace')) { | |
$namespace = $this->compiler->getOption('namespace'); | |
} else if ($this->compiler->getOption('package')) { | |
$namespace = $this->compiler->getOption('package'); | |
} else if (isset($opts['php.namespace'])) { | |
$namespace = $opts['php.namespace']; | |
} else { | |
$namespace = parent::getNamespace($proto); | |
} | |
$namespace = trim($namespace, '.\\'); | |
return str_replace('.', '\\', $namespace); | |
} | |
public function generate(proto\FileDescriptorProto $proto) | |
{ | |
parent::generate($proto); | |
$this->components = array(); | |
$namespace = $proto->getPackage(); | |
// Generate Enums | |
foreach ($proto->getEnumType() as $enum) { | |
$src = $this->compileEnum($enum, $namespace); | |
$this->addComponent($namespace, $enum->getName(), $src); | |
} | |
// Generate Messages | |
foreach ($proto->getMessageType() as $msg) { | |
$src = $this->compileMessage($msg, $namespace); | |
$this->addComponent($namespace, $msg->getName(), $src); | |
} | |
// Generate services | |
if ($this->getOption('generic_services') && count($proto->hasService())): | |
foreach ($proto->getServiceList() as $service) { | |
$src = $this->compileService($service, $namespace); | |
$this->addComponent($namespace, $service->getName(), $src); | |
} | |
endif; | |
// Collect extensions | |
if ($proto->hasExtension()) { | |
foreach ($proto->getExtensionList() as $field) { | |
$this->extensions[$field->getExtendee()][] = array($namespace, $field); | |
} | |
} | |
// Dump all extensions found in this proto file | |
if (count($this->extensions)): | |
$s[]= 'namespace {'; | |
foreach ($this->extensions as $extendee => $fields) { | |
foreach ($fields as $pair) { | |
list($ns, $field) = $pair; | |
$s[] = $this->compileExtension($field, $ns, ' '); | |
} | |
} | |
$s[]= '}'; | |
$src = implode(PHP_EOL, $s); | |
// In multifile mode we output all the extensions in a file named after | |
// the proto file, since it's not trivial or even possible in all cases | |
// to include the extensions with the extended message file. | |
$fname = pathinfo($proto->getName(), PATHINFO_FILENAME); | |
$this->addComponent(null, $fname . '-extensions', $src); | |
// Reset extensions for next proto file | |
$this->extensions = array(); | |
endif; | |
$files = array(); | |
if (!$this->getOption('multifile')) { | |
$src = ''; | |
foreach ($this->components as $content) { | |
$src .= $content; | |
} | |
$fname = pathinfo($proto->getName(), PATHINFO_FILENAME); | |
$files[] = $this->buildFile($proto, $fname, $src); | |
} else { | |
foreach ($this->components as $ns => $content) { | |
$fname = str_replace('\\', '/', $ns); | |
$files[] = $this->buildFile($proto, $fname, $content); | |
} | |
} | |
return $files; | |
} | |
protected function buildFile(proto\FileDescriptorProto $proto, $fname, $contents) | |
{ | |
$suffix = $this->getOption('suffix') ?: '.php'; | |
$fname .= $suffix; | |
$file = new \google\protobuf\compiler\CodeGeneratorResponse\File(); | |
$file->setName($fname); | |
$s = array(); | |
$s[]= "<?php"; | |
$s[]= "// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin " . Protobuf::VERSION; | |
$s[]= "// Source: " . $proto->getName(); | |
$s[]= "// Date: " . date('Y-m-d H:i:s'); | |
$s[]= ""; | |
$s[]= "// @@protoc_insertion_point(scope_file)"; | |
$s[]= ""; | |
$contents = implode(PHP_EOL, $s) . PHP_EOL . $contents; | |
$file->setContent($contents); | |
return $file; | |
} | |
protected function compileEnum(proto\EnumDescriptorProto $enum, $ns) | |
{ | |
$s = array(); | |
$s[]= "namespace " . $this->normalizeNS($ns) . " {"; | |
$s[]= ""; | |
$s[]= " // @@protoc_insertion_point(scope_namespace)"; | |
$s[]= " // @@protoc_insertion_point(namespace_$ns)"; | |
$s[]= ""; | |
$cmt = $this->compiler->getComment($ns . '.' . $enum->getName(), ' * '); | |
if ($cmt): | |
$s[]= " /**"; | |
$s[]= $cmt; | |
$s[]= " */"; | |
endif; | |
$s[]= " class " . $enum->getName() . " {"; | |
foreach ($enum->getValueList() as $value): | |
$s[]= " const " . $value->getName() . " = " . $value->getNumber() . ";"; | |
endforeach; | |
$s[]= ""; | |
$s[]= " // @@protoc_insertion_point(scope_class)"; | |
$s[]= ' // @@protoc_insertion_point(class_' . $ns . '.' . $enum->getName() . ')'; | |
$s[]= " }"; | |
$s[]= "}"; | |
$s[]= ""; | |
return implode(PHP_EOL, $s); | |
} | |
protected function compileMessage(proto\DescriptorProto $msg, $ns) | |
{ | |
$s = array(); | |
$s[]= "namespace " . $this->normalizeNS($ns) . " {"; | |
$s[]= ""; | |
$s[]= " // @@protoc_insertion_point(scope_namespace)"; | |
$s[]= " // @@protoc_insertion_point(namespace_$ns)"; | |
$s[]= ""; | |
$cmt = $this->compiler->getComment($ns . '.' . $msg->getName(), ' * '); | |
if ($cmt): | |
$s[]= " /**"; | |
$s[]= $cmt; | |
$s[]= " */"; | |
endif; | |
// Compute a new namespace with the message name as suffix | |
$ns .= '.' . $msg->getName(); | |
$s[]= ' class ' . $msg->getName() . ' extends \DrSlump\Protobuf\Message {'; | |
$s[]= ""; | |
$s[]= ' /** @var \Closure[] */'; | |
$s[]= ' protected static $__extensions = array();'; | |
$s[]= ''; | |
$s[]= ' public static function descriptor()'; | |
$s[]= ' {'; | |
$s[]= ' $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, \'' . $ns . '\');'; | |
$s[]= ''; | |
foreach ($msg->getField() as $field): | |
$s[]= $this->compileField($field, $ns, " "); | |
$s[]= ' $descriptor->addField($f);'; | |
$s[]= ''; | |
endforeach; | |
$s[]= ' foreach (self::$__extensions as $cb) {'; | |
$s[]= ' $descriptor->addField($cb(), true);'; | |
$s[]= ' }'; | |
$s[]= ''; | |
$s[]= ' // @@protoc_insertion_point(scope_descriptor)'; | |
$s[]= ' // @@protoc_insertion_point(descriptor_' . $ns . ')'; | |
$s[]= ''; | |
$s[]= ' return $descriptor;'; | |
$s[]= ' }'; | |
$s[]= ''; | |
//$s[]= " protected static \$__exts = array("; | |
//foreach ($msg->getExtensionRange() as $range): | |
//$s[]= ' array(' . $range->getStart() . ', ' . ($range->getEnd()-1) . '),'; | |
//endforeach; | |
//$s[]= " );"; | |
//$s[]= ""; | |
foreach ($msg->getField() as $field): | |
$s[]= $this->generatePublicField($field, $ns, " "); | |
endforeach; | |
$s[]= ""; | |
foreach ($msg->getField() as $field): | |
$s[]= $this->generateAccessors($field, $ns, " "); | |
endforeach; | |
$s[]= ""; | |
$s[]= " // @@protoc_insertion_point(scope_class)"; | |
$s[]= ' // @@protoc_insertion_point(class_' . $ns . ')'; | |
$s[]= " }"; | |
$s[]= "}"; | |
$s[]= ""; | |
// Generate Enums | |
if ($msg->hasEnumType()): | |
foreach ($msg->getEnumType() as $enum): | |
$src = $this->compileEnum($enum, $ns); | |
$this->addComponent($ns, $enum->getName(), $src); | |
endforeach; | |
endif; | |
// Generate nested messages | |
if ($msg->hasNestedType()): | |
foreach ($msg->getNestedType() as $msg): | |
$src = $this->compileMessage($msg, $ns); | |
$this->addComponent($ns, $msg->getName(), $src); | |
endforeach; | |
endif; | |
// Collect extensions | |
if ($msg->hasExtension()) { | |
foreach ($msg->getExtensionList() as $field) { | |
$this->_extensions[$field->getExtendee()][] = array($ns, $field); | |
} | |
} | |
return implode(PHP_EOL, $s) . PHP_EOL; | |
} | |
protected function compileField(proto\FieldDescriptorProto $field, $ns, $indent) | |
{ | |
switch ($field->getLabel()) { | |
case Protobuf::RULE_REQUIRED: | |
$rule = 'required'; | |
break; | |
case Protobuf::RULE_OPTIONAL: | |
$rule = 'optional'; | |
break; | |
case Protobuf::RULE_REPEATED: | |
$rule = 'repeated'; | |
break; | |
} | |
$s[]= "// $rule " . $field->getTypeName() . " " . $field->getName() . " = " . $field->getNumber(); | |
$s[]= '$f = new \DrSlump\Protobuf\Field();'; | |
$s[]= '$f->number = ' . $field->getNumber() . ';'; | |
$s[]= '$f->name = "'. $field->getName() . '";'; | |
$s[]= '$f->type = ' . $field->getType() . ';'; | |
$s[]= '$f->rule = ' . $field->getLabel() . ';'; | |
if ($field->hasTypeName()): | |
$ref = $field->getTypeName(); | |
if (substr($ref, 0, 1) !== '.') { | |
throw new \RuntimeException("Only fully qualified names are supported but found '$ref' at $ns"); | |
} | |
$s[]= '$f->reference = \'\\' . $this->normalizeNS($ref) . "';"; | |
endif; | |
if ($field->hasDefaultValue()): | |
switch ($field->getType()) { | |
case Protobuf::TYPE_BOOL: | |
$bool = filter_var($field->getDefaultValue(), FILTER_VALIDATE_BOOLEAN); | |
$s[]= '$f->default = ' . ($bool ? 'true' : 'false') . ';'; | |
break; | |
case Protobuf::TYPE_STRING: | |
$s[]= '$f->default = "' . addcslashes($field->getDefaultValue(), '"\\') . '";'; | |
break; | |
case Protobuf::TYPE_ENUM: | |
$value = '\\' . $this->normalizeNS($field->getTypeName()) . '::' . $field->getDefaultValue(); | |
$s[]= '$f->default = ' . $value . ';'; | |
break; | |
default: // Numbers | |
$s[]= '$f->default = ' . $field->getDefaultValue() . ';'; | |
} | |
endif; | |
$s[]= '// @@protoc_insertion_point(scope_field)'; | |
$s[]= '// @@protoc_insertion_point(field_' . $ns . ':' . $field->getName() . ')'; | |
return $indent . implode(PHP_EOL.$indent, $s); | |
} | |
protected function compileExtension(proto\FieldDescriptorProto $field, $ns, $indent) | |
{ | |
$extendee = $this->normalizeNS($field->getExtendee()); | |
$name = $this->normalizeNS($ns . '.' . $field->getName()); | |
$field->setName($name); | |
$s[]= "\\$extendee::extension(function(){"; | |
$s[]= $this->compileField($field, $ns, $indent.' '); | |
$s[]= ' // @@protoc_insertion_point(scope_extension)'; | |
$s[]= ' // @@protoc_insertion_point(extension_' . $ns . ':' . $field->getName() . ')'; | |
$s[]= ' return $f;'; | |
$s[]= "});"; | |
return $indent . implode(PHP_EOL.$indent, $s); | |
} | |
protected function compileService(proto\ServiceDescriptorProto $service, $ns) | |
{ | |
$s = array(); | |
$s[]= 'namespace ' . $this->normalizeNS($ns) . ' {'; | |
$s[]= ''; | |
$s[]= " // @@protoc_insertion_point(scope_namespace)"; | |
$s[]= " // @@protoc_insertion_point(namespace_$ns)"; | |
$s[]= ''; | |
$cmt = $this->compiler->getComment($ns . '.' . $service->getName(), ' * '); | |
if ($cmt): | |
$s[]= " /**"; | |
$s[]= $cmt; | |
$s[]= " */"; | |
endif; | |
$s[]= ' interface ' . $service->getName(); | |
$s[]= ' {'; | |
$s[]= ' // @@protoc_insertion_point(scope_interface)'; | |
$s[]= ' // @@protoc_insertion_point(interface_' . $ns . '.' . $service->getName() . ')'; | |
$s[]= ''; | |
foreach ($service->getMethodList() as $method): | |
$s[]= ' /**'; | |
$cmt = $this->compiler->getComment($ns . '.' . $service->getName() . '.' . $method->getName(), ' * '); | |
if ($cmt): | |
$s[]= $cmt; | |
$s[]= ' * '; | |
endif; | |
$s[]= ' * @param ' . $this->normalizeNS($method->getInputType()) . ' $input'; | |
$s[]= ' * @return ' . $this->normalizeNS($method->getOutputType()); | |
$s[]= ' */'; | |
$s[]= ' public function ' . $method->getName() . '(' . $this->normalizeNS($method->getInputType()) . ' $input);'; | |
$s[]= ''; | |
endforeach; | |
$s[]= ' }'; | |
$s[]= '}'; | |
$s[]= ''; | |
return implode(PHP_EOL, $s) . PHP_EOL; | |
} | |
protected function generatePublicField(proto\FieldDescriptorProto $field, $ns, $indent) | |
{ | |
$cmt = $this->compiler->getComment($ns . '.' . $field->getNumber(), "$indent * "); | |
if ($cmt) { | |
$cmt = "\n" . $cmt . "\n$indent *"; | |
} | |
if ($field->getLabel() === Protobuf::RULE_REPEATED) { | |
$s[]= "/** $cmt @var " . $this->getJavaDocType($field) . "[] " . ($cmt ? "\n$indent" : '') . " */"; | |
$s[]= 'public $' . $field->getName() . " = array();"; | |
} else { | |
$s[]= "/** $cmt @var " . $this->getJavaDocType($field) . ($cmt ? "\n$indent" : '') . " */"; | |
$default = 'null'; | |
if ($field->hasDefaultValue()) { | |
switch ($field->getType()) { | |
case Protobuf::TYPE_BOOL: | |
$default = $field->getDefaultValue() ? 'true' : 'false'; | |
break; | |
case Protobuf::TYPE_STRING: | |
$default = '"' . addcslashes($field->getDefaultValue(), '"\\') . '"'; | |
break; | |
case Protobuf::TYPE_ENUM: | |
$default = '\\' . $this->normalizeNS($field->getTypeName()) . '::' . $field->getDefaultValue(); | |
break; | |
default: // Numbers | |
$default = $field->getDefaultValue(); | |
} | |
} | |
$s[]= 'public $' . $field->getName() . ' = ' . $default . ';'; | |
} | |
$s[]= ""; | |
return $indent . implode(PHP_EOL.$indent, $s); | |
} | |
protected function generateAccessors(proto\FieldDescriptorProto $field, $ns, $indent) | |
{ | |
$tag = $field->getNumber(); | |
$name = $field->getName(); | |
$camel = $this->compiler->camelize(ucfirst($name)); | |
$typehint = ''; | |
$typedoc = $this->getJavaDocType($field); | |
if (0 === strpos($typedoc, '\\')) { | |
$typehint = $typedoc; | |
} | |
// hasXXX | |
$s[]= "/**"; | |
$s[]= " * Check if <$name> has a value"; | |
$s[]= " *"; | |
$s[]= " * @return boolean"; | |
$s[]= " */"; | |
$s[]= "public function has$camel(){"; | |
$s[]= " return \$this->_has($tag);"; | |
$s[]= "}"; | |
$s[]= ""; | |
// clearXXX | |
$s[]= "/**"; | |
$s[]= " * Clear <$name> value"; | |
$s[]= " *"; | |
$s[]= " * @return \\" . $this->normalizeNS($ns); | |
$s[]= " */"; | |
$s[]= "public function clear$camel(){"; | |
$s[]= " return \$this->_clear($tag);"; | |
$s[]= "}"; | |
$s[]= ""; | |
if ($field->getLabel() === Protobuf::RULE_REPEATED): | |
// getXXX | |
$s[]= "/**"; | |
$s[]= " * Get <$name> value"; | |
$s[]= " *"; | |
$s[]= " * @param int \$idx"; | |
$s[]= " * @return $typedoc"; | |
$s[]= " */"; | |
$s[]= "public function get$camel(\$idx = NULL){"; | |
$s[]= " return \$this->_get($tag, \$idx);"; | |
$s[]= "}"; | |
$s[]= ""; | |
// setXXX | |
$s[]= "/**"; | |
$s[]= " * Set <$name> value"; | |
$s[]= " *"; | |
$s[]= " * @param $typedoc \$value"; | |
$s[]= " * @return \\" . $this->normalizeNS($ns); | |
$s[]= " */"; | |
$s[]= "public function set$camel($typehint \$value, \$idx = NULL){"; | |
$s[]= " return \$this->_set($tag, \$value, \$idx);"; | |
$s[]= "}"; | |
$s[]= ""; | |
$s[]= "/**"; | |
$s[]= " * Get all elements of <$name>"; | |
$s[]= " *"; | |
$s[]= " * @return {$typedoc}[]"; | |
$s[]= " */"; | |
$s[]= "public function get{$camel}List(){"; | |
$s[]= " return \$this->_get($tag);"; | |
$s[]= "}"; | |
$s[]= ""; | |
$s[]= "/**"; | |
$s[]= " * Add a new element to <$name>"; | |
$s[]= " *"; | |
$s[]= " * @param $typedoc \$value"; | |
$s[]= " * @return \\" . $this->normalizeNS($ns); | |
$s[]= " */"; | |
$s[]= "public function add$camel($typehint \$value){"; | |
$s[]= " return \$this->_add($tag, \$value);"; | |
$s[]= "}"; | |
$s[]= ""; | |
else: | |
// getXXX | |
$s[]= "/**"; | |
$s[]= " * Get <$name> value"; | |
$s[]= " *"; | |
$s[]= " * @return $typedoc"; | |
$s[]= " */"; | |
$s[]= "public function get$camel(){"; | |
$s[]= " return \$this->_get($tag);"; | |
$s[]= "}"; | |
$s[]= ""; | |
// setXXX | |
$s[]= "/**"; | |
$s[]= " * Set <$name> value"; | |
$s[]= " *"; | |
$s[]= " * @param $typedoc \$value"; | |
$s[]= " * @return \\" . $this->normalizeNS($ns); | |
$s[]= " */"; | |
$s[]= "public function set$camel($typehint \$value){"; | |
$s[]= " return \$this->_set($tag, \$value);"; | |
$s[]= "}"; | |
$s[]= ""; | |
endif; | |
return $indent . implode(PHP_EOL.$indent, $s); | |
} | |
protected function getJavaDocType(proto\FieldDescriptorProto $field) | |
{ | |
switch ($field->getType()) { | |
case Protobuf::TYPE_DOUBLE: | |
case Protobuf::TYPE_FLOAT: | |
return 'float'; | |
case Protobuf::TYPE_INT64: | |
case Protobuf::TYPE_UINT64: | |
case Protobuf::TYPE_INT32: | |
case Protobuf::TYPE_FIXED64: | |
case Protobuf::TYPE_FIXED32: | |
case Protobuf::TYPE_UINT32: | |
case Protobuf::TYPE_SFIXED32: | |
case Protobuf::TYPE_SFIXED64: | |
case Protobuf::TYPE_SINT32: | |
case Protobuf::TYPE_SINT64: | |
return 'int'; | |
case Protobuf::TYPE_BOOL: | |
return 'boolean'; | |
case Protobuf::TYPE_STRING: | |
return 'string'; | |
case Protobuf::TYPE_MESSAGE: | |
return '\\' . $this->normalizeNS($field->getTypeName()); | |
case Protobuf::TYPE_BYTES: | |
return 'string'; | |
case Protobuf::TYPE_ENUM: | |
return 'int - \\' . $this->normalizeNS($field->getTypeName()); | |
case Protobuf::TYPE_GROUP: | |
default: | |
return 'unknown'; | |
} | |
} | |
protected function normalizeNS($package) | |
{ | |
// Remove leading dot (used in references) | |
$package = ltrim($package, '.'); | |
if ($this->compiler->hasPackage($package)) { | |
return $this->compiler->getPackage($package); | |
} | |
// Check the currently registered packages to find a root one | |
$found = null; | |
foreach ($this->compiler->getPackages() as $pkg=>$ns) { | |
// Keep only the longest match | |
if (0 === strpos($package, $pkg.'.') && strlen($found) < strlen($pkg)) { | |
$found = $pkg; | |
} | |
} | |
// If no matching package was found issue a warning and use the package name | |
if (!$found) { | |
$this->compiler->warning('Non tracked package name found "' . $package . '"'); | |
$namespace = str_replace('.', '\\', $package); | |
} else { | |
// Complete the namespace with the remaining package | |
$namespace = $this->compiler->getPackage($found); | |
$namespace .= substr($package, strlen($found)); | |
$namespace = str_replace('.', '\\', $namespace); | |
// Set the newly found namespace in the registry | |
$this->compiler->setPackage($package, $namespace); | |
} | |
return $namespace; | |
} | |
} | |
<?php | |
// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@ | |
// Source: descriptor.proto | |
// Date: 2011-03-20 01:26:49 | |
namespace google\protobuf { | |
class FileDescriptorSet extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FileDescriptorSet"); | |
// repeated .google.protobuf.FileDescriptorProto file = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "file"; | |
$f->nameOrig = "file"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\FileDescriptorProto"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\FileDescriptorProto[] */ | |
public $file = array(); | |
/** | |
* Check if <file> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasFile(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <file> value | |
* | |
* @return \google\protobuf\FileDescriptorSet | |
*/ | |
public function clearFile(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <file> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function getFile($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <file> value | |
* | |
* @param \google\protobuf\FileDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorSet | |
*/ | |
public function setFile(\google\protobuf\FileDescriptorProto $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <file> | |
* | |
* @return \google\protobuf\FileDescriptorProto[] | |
*/ | |
public function getFileList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <file> | |
* | |
* @param \google\protobuf\FileDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorSet | |
*/ | |
public function addFile(\google\protobuf\FileDescriptorProto $value){ | |
return $this->_add(1, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class FileDescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FileDescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional package = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "package"; | |
$f->nameOrig = "package"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated dependency = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "dependency"; | |
$f->nameOrig = "dependency"; | |
$f->type = 9; | |
$f->rule = 3; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.DescriptorProto message_type = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "message_type"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\DescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.EnumDescriptorProto enum_type = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "enum_type"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\EnumDescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.ServiceDescriptorProto service = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "service"; | |
$f->nameOrig = "service"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\ServiceDescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.FieldDescriptorProto extension = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "extension"; | |
$f->nameOrig = "extension"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\FieldDescriptorProto"; | |
$descriptor->addField($f); | |
// optional .google.protobuf.FileOptions options = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\FileOptions"; | |
$descriptor->addField($f); | |
// optional .google.protobuf.SourceCodeInfo source_code_info = 9 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 9; | |
$f->name = "source_code_info"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\SourceCodeInfo"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var string */ | |
public $package = null; | |
/** @var string[] */ | |
public $dependency = array(); | |
/** @var \google\protobuf\DescriptorProto[] */ | |
public $message_type = array(); | |
/** @var \google\protobuf\EnumDescriptorProto[] */ | |
public $enum_type = array(); | |
/** @var \google\protobuf\ServiceDescriptorProto[] */ | |
public $service = array(); | |
/** @var \google\protobuf\FieldDescriptorProto[] */ | |
public $extension = array(); | |
/** @var \google\protobuf\FileOptions */ | |
public $options = null; | |
/** @var \google\protobuf\SourceCodeInfo */ | |
public $source_code_info = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <package> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPackage(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <package> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearPackage(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <package> value | |
* | |
* @return string | |
*/ | |
public function getPackage(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <package> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setPackage( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <dependency> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDependency(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <dependency> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearDependency(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <dependency> value | |
* | |
* @param int $idx | |
* @return string | |
*/ | |
public function getDependency($idx = NULL){ | |
return $this->_get(3, $idx); | |
} | |
/** | |
* Set <dependency> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setDependency( $value, $idx = NULL){ | |
return $this->_set(3, $value, $idx); | |
} | |
/** | |
* Get all elements of <dependency> | |
* | |
* @return string[] | |
*/ | |
public function getDependencyList(){ | |
return $this->_get(3); | |
} | |
/** | |
* Add a new element to <dependency> | |
* | |
* @param string $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function addDependency( $value){ | |
return $this->_add(3, $value); | |
} | |
/** | |
* Check if <message_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasMessageType(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <message_type> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearMessageType(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <message_type> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function getMessageType($idx = NULL){ | |
return $this->_get(4, $idx); | |
} | |
/** | |
* Set <message_type> value | |
* | |
* @param \google\protobuf\DescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setMessageType(\google\protobuf\DescriptorProto $value, $idx = NULL){ | |
return $this->_set(4, $value, $idx); | |
} | |
/** | |
* Get all elements of <message_type> | |
* | |
* @return \google\protobuf\DescriptorProto[] | |
*/ | |
public function getMessageTypeList(){ | |
return $this->_get(4); | |
} | |
/** | |
* Add a new element to <message_type> | |
* | |
* @param \google\protobuf\DescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function addMessageType(\google\protobuf\DescriptorProto $value){ | |
return $this->_add(4, $value); | |
} | |
/** | |
* Check if <enum_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEnumType(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <enum_type> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearEnumType(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <enum_type> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function getEnumType($idx = NULL){ | |
return $this->_get(5, $idx); | |
} | |
/** | |
* Set <enum_type> value | |
* | |
* @param \google\protobuf\EnumDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setEnumType(\google\protobuf\EnumDescriptorProto $value, $idx = NULL){ | |
return $this->_set(5, $value, $idx); | |
} | |
/** | |
* Get all elements of <enum_type> | |
* | |
* @return \google\protobuf\EnumDescriptorProto[] | |
*/ | |
public function getEnumTypeList(){ | |
return $this->_get(5); | |
} | |
/** | |
* Add a new element to <enum_type> | |
* | |
* @param \google\protobuf\EnumDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function addEnumType(\google\protobuf\EnumDescriptorProto $value){ | |
return $this->_add(5, $value); | |
} | |
/** | |
* Check if <service> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasService(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <service> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearService(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <service> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function getService($idx = NULL){ | |
return $this->_get(6, $idx); | |
} | |
/** | |
* Set <service> value | |
* | |
* @param \google\protobuf\ServiceDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setService(\google\protobuf\ServiceDescriptorProto $value, $idx = NULL){ | |
return $this->_set(6, $value, $idx); | |
} | |
/** | |
* Get all elements of <service> | |
* | |
* @return \google\protobuf\ServiceDescriptorProto[] | |
*/ | |
public function getServiceList(){ | |
return $this->_get(6); | |
} | |
/** | |
* Add a new element to <service> | |
* | |
* @param \google\protobuf\ServiceDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function addService(\google\protobuf\ServiceDescriptorProto $value){ | |
return $this->_add(6, $value); | |
} | |
/** | |
* Check if <extension> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasExtension(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <extension> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearExtension(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <extension> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function getExtension($idx = NULL){ | |
return $this->_get(7, $idx); | |
} | |
/** | |
* Set <extension> value | |
* | |
* @param \google\protobuf\FieldDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setExtension(\google\protobuf\FieldDescriptorProto $value, $idx = NULL){ | |
return $this->_set(7, $value, $idx); | |
} | |
/** | |
* Get all elements of <extension> | |
* | |
* @return \google\protobuf\FieldDescriptorProto[] | |
*/ | |
public function getExtensionList(){ | |
return $this->_get(7); | |
} | |
/** | |
* Add a new element to <extension> | |
* | |
* @param \google\protobuf\FieldDescriptorProto $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function addExtension(\google\protobuf\FieldDescriptorProto $value){ | |
return $this->_add(7, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\FileOptions $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\FileOptions $value){ | |
return $this->_set(8, $value); | |
} | |
/** | |
* Check if <source_code_info> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSourceCodeInfo(){ | |
return $this->_has(9); | |
} | |
/** | |
* Clear <source_code_info> value | |
* | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function clearSourceCodeInfo(){ | |
return $this->_clear(9); | |
} | |
/** | |
* Get <source_code_info> value | |
* | |
* @return \google\protobuf\SourceCodeInfo | |
*/ | |
public function getSourceCodeInfo(){ | |
return $this->_get(9); | |
} | |
/** | |
* Set <source_code_info> value | |
* | |
* @param \google\protobuf\SourceCodeInfo $value | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function setSourceCodeInfo(\google\protobuf\SourceCodeInfo $value){ | |
return $this->_set(9, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class DescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\DescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.FieldDescriptorProto field = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "field"; | |
$f->nameOrig = "field"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\FieldDescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.FieldDescriptorProto extension = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "extension"; | |
$f->nameOrig = "extension"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\FieldDescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.DescriptorProto nested_type = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "nested_type"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\DescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.EnumDescriptorProto enum_type = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "enum_type"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\EnumDescriptorProto"; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "extension_range"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\DescriptorProto\ExtensionRange"; | |
$descriptor->addField($f); | |
// optional .google.protobuf.MessageOptions options = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\MessageOptions"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var \google\protobuf\FieldDescriptorProto[] */ | |
public $field = array(); | |
/** @var \google\protobuf\FieldDescriptorProto[] */ | |
public $extension = array(); | |
/** @var \google\protobuf\DescriptorProto[] */ | |
public $nested_type = array(); | |
/** @var \google\protobuf\EnumDescriptorProto[] */ | |
public $enum_type = array(); | |
/** @var \google\protobuf\DescriptorProto\ExtensionRange[] */ | |
public $extension_range = array(); | |
/** @var \google\protobuf\MessageOptions */ | |
public $options = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <field> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasField(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <field> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearField(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <field> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function getField($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <field> value | |
* | |
* @param \google\protobuf\FieldDescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setField(\google\protobuf\FieldDescriptorProto $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <field> | |
* | |
* @return \google\protobuf\FieldDescriptorProto[] | |
*/ | |
public function getFieldList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <field> | |
* | |
* @param \google\protobuf\FieldDescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function addField(\google\protobuf\FieldDescriptorProto $value){ | |
return $this->_add(2, $value); | |
} | |
/** | |
* Check if <extension> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasExtension(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <extension> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearExtension(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <extension> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function getExtension($idx = NULL){ | |
return $this->_get(6, $idx); | |
} | |
/** | |
* Set <extension> value | |
* | |
* @param \google\protobuf\FieldDescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setExtension(\google\protobuf\FieldDescriptorProto $value, $idx = NULL){ | |
return $this->_set(6, $value, $idx); | |
} | |
/** | |
* Get all elements of <extension> | |
* | |
* @return \google\protobuf\FieldDescriptorProto[] | |
*/ | |
public function getExtensionList(){ | |
return $this->_get(6); | |
} | |
/** | |
* Add a new element to <extension> | |
* | |
* @param \google\protobuf\FieldDescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function addExtension(\google\protobuf\FieldDescriptorProto $value){ | |
return $this->_add(6, $value); | |
} | |
/** | |
* Check if <nested_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNestedType(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <nested_type> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearNestedType(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <nested_type> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function getNestedType($idx = NULL){ | |
return $this->_get(3, $idx); | |
} | |
/** | |
* Set <nested_type> value | |
* | |
* @param \google\protobuf\DescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setNestedType(\google\protobuf\DescriptorProto $value, $idx = NULL){ | |
return $this->_set(3, $value, $idx); | |
} | |
/** | |
* Get all elements of <nested_type> | |
* | |
* @return \google\protobuf\DescriptorProto[] | |
*/ | |
public function getNestedTypeList(){ | |
return $this->_get(3); | |
} | |
/** | |
* Add a new element to <nested_type> | |
* | |
* @param \google\protobuf\DescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function addNestedType(\google\protobuf\DescriptorProto $value){ | |
return $this->_add(3, $value); | |
} | |
/** | |
* Check if <enum_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEnumType(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <enum_type> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearEnumType(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <enum_type> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function getEnumType($idx = NULL){ | |
return $this->_get(4, $idx); | |
} | |
/** | |
* Set <enum_type> value | |
* | |
* @param \google\protobuf\EnumDescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setEnumType(\google\protobuf\EnumDescriptorProto $value, $idx = NULL){ | |
return $this->_set(4, $value, $idx); | |
} | |
/** | |
* Get all elements of <enum_type> | |
* | |
* @return \google\protobuf\EnumDescriptorProto[] | |
*/ | |
public function getEnumTypeList(){ | |
return $this->_get(4); | |
} | |
/** | |
* Add a new element to <enum_type> | |
* | |
* @param \google\protobuf\EnumDescriptorProto $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function addEnumType(\google\protobuf\EnumDescriptorProto $value){ | |
return $this->_add(4, $value); | |
} | |
/** | |
* Check if <extension_range> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasExtensionRange(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <extension_range> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearExtensionRange(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <extension_range> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\DescriptorProto\ExtensionRange | |
*/ | |
public function getExtensionRange($idx = NULL){ | |
return $this->_get(5, $idx); | |
} | |
/** | |
* Set <extension_range> value | |
* | |
* @param \google\protobuf\DescriptorProto\ExtensionRange $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setExtensionRange(\google\protobuf\DescriptorProto\ExtensionRange $value, $idx = NULL){ | |
return $this->_set(5, $value, $idx); | |
} | |
/** | |
* Get all elements of <extension_range> | |
* | |
* @return \google\protobuf\DescriptorProto\ExtensionRange[] | |
*/ | |
public function getExtensionRangeList(){ | |
return $this->_get(5); | |
} | |
/** | |
* Add a new element to <extension_range> | |
* | |
* @param \google\protobuf\DescriptorProto\ExtensionRange $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function addExtensionRange(\google\protobuf\DescriptorProto\ExtensionRange $value){ | |
return $this->_add(5, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(7); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\MessageOptions $value | |
* @return \google\protobuf\DescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\MessageOptions $value){ | |
return $this->_set(7, $value); | |
} | |
} | |
} | |
namespace google\protobuf\DescriptorProto { | |
class ExtensionRange extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\DescriptorProto\ExtensionRange"); | |
// optional start = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "start"; | |
$f->nameOrig = "start"; | |
$f->type = 5; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional end = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "end"; | |
$f->nameOrig = "end"; | |
$f->type = 5; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var int */ | |
public $start = null; | |
/** @var int */ | |
public $end = null; | |
/** | |
* Check if <start> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStart(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <start> value | |
* | |
* @return \google\protobuf\DescriptorProto\ExtensionRange | |
*/ | |
public function clearStart(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <start> value | |
* | |
* @return int | |
*/ | |
public function getStart(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <start> value | |
* | |
* @param int $value | |
* @return \google\protobuf\DescriptorProto\ExtensionRange | |
*/ | |
public function setStart( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <end> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEnd(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <end> value | |
* | |
* @return \google\protobuf\DescriptorProto\ExtensionRange | |
*/ | |
public function clearEnd(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <end> value | |
* | |
* @return int | |
*/ | |
public function getEnd(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <end> value | |
* | |
* @param int $value | |
* @return \google\protobuf\DescriptorProto\ExtensionRange | |
*/ | |
public function setEnd( $value){ | |
return $this->_set(2, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class FieldDescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FieldDescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional number = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "number"; | |
$f->nameOrig = "number"; | |
$f->type = 5; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional .google.protobuf.FieldDescriptorProto.Label label = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "label"; | |
$f->nameOrig = "label"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\FieldDescriptorProto\Label"; | |
$descriptor->addField($f); | |
// optional .google.protobuf.FieldDescriptorProto.Type type = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "type"; | |
$f->nameOrig = "type"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\FieldDescriptorProto\Type"; | |
$descriptor->addField($f); | |
// optional type_name = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "type_name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional extendee = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "extendee"; | |
$f->nameOrig = "extendee"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional default_value = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "default_value"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional .google.protobuf.FieldOptions options = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\FieldOptions"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var int */ | |
public $number = null; | |
/** @var int - \google\protobuf\FieldDescriptorProto\Label */ | |
public $label = null; | |
/** @var int - \google\protobuf\FieldDescriptorProto\Type */ | |
public $type = null; | |
/** @var string */ | |
public $type_name = null; | |
/** @var string */ | |
public $extendee = null; | |
/** @var string */ | |
public $default_value = null; | |
/** @var \google\protobuf\FieldOptions */ | |
public $options = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <number> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNumber(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <number> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearNumber(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <number> value | |
* | |
* @return int | |
*/ | |
public function getNumber(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <number> value | |
* | |
* @param int $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setNumber( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <label> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLabel(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <label> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearLabel(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <label> value | |
* | |
* @return int - \google\protobuf\FieldDescriptorProto\Label | |
*/ | |
public function getLabel(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <label> value | |
* | |
* @param int - \google\protobuf\FieldDescriptorProto\Label $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setLabel( $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasType(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <type> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearType(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <type> value | |
* | |
* @return int - \google\protobuf\FieldDescriptorProto\Type | |
*/ | |
public function getType(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <type> value | |
* | |
* @param int - \google\protobuf\FieldDescriptorProto\Type $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setType( $value){ | |
return $this->_set(5, $value); | |
} | |
/** | |
* Check if <type_name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasTypeName(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <type_name> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearTypeName(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <type_name> value | |
* | |
* @return string | |
*/ | |
public function getTypeName(){ | |
return $this->_get(6); | |
} | |
/** | |
* Set <type_name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setTypeName( $value){ | |
return $this->_set(6, $value); | |
} | |
/** | |
* Check if <extendee> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasExtendee(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <extendee> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearExtendee(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <extendee> value | |
* | |
* @return string | |
*/ | |
public function getExtendee(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <extendee> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setExtendee( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <default_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDefaultValue(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <default_value> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearDefaultValue(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <default_value> value | |
* | |
* @return string | |
*/ | |
public function getDefaultValue(){ | |
return $this->_get(7); | |
} | |
/** | |
* Set <default_value> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setDefaultValue( $value){ | |
return $this->_set(7, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\FieldOptions $value | |
* @return \google\protobuf\FieldDescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\FieldOptions $value){ | |
return $this->_set(8, $value); | |
} | |
} | |
} | |
namespace google\protobuf\FieldDescriptorProto { | |
class Type { | |
const TYPE_DOUBLE = 1; | |
const TYPE_FLOAT = 2; | |
const TYPE_INT64 = 3; | |
const TYPE_UINT64 = 4; | |
const TYPE_INT32 = 5; | |
const TYPE_FIXED64 = 6; | |
const TYPE_FIXED32 = 7; | |
const TYPE_BOOL = 8; | |
const TYPE_STRING = 9; | |
const TYPE_GROUP = 10; | |
const TYPE_MESSAGE = 11; | |
const TYPE_BYTES = 12; | |
const TYPE_UINT32 = 13; | |
const TYPE_ENUM = 14; | |
const TYPE_SFIXED32 = 15; | |
const TYPE_SFIXED64 = 16; | |
const TYPE_SINT32 = 17; | |
const TYPE_SINT64 = 18; | |
} | |
} | |
namespace google\protobuf\FieldDescriptorProto { | |
class Label { | |
const LABEL_OPTIONAL = 1; | |
const LABEL_REQUIRED = 2; | |
const LABEL_REPEATED = 3; | |
} | |
} | |
namespace google\protobuf { | |
class EnumDescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumDescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.EnumValueDescriptorProto value = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "value"; | |
$f->nameOrig = "value"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\EnumValueDescriptorProto"; | |
$descriptor->addField($f); | |
// optional .google.protobuf.EnumOptions options = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\EnumOptions"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var \google\protobuf\EnumValueDescriptorProto[] */ | |
public $value = array(); | |
/** @var \google\protobuf\EnumOptions */ | |
public $options = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasValue(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <value> value | |
* | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function clearValue(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <value> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function getValue($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <value> value | |
* | |
* @param \google\protobuf\EnumValueDescriptorProto $value | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function setValue(\google\protobuf\EnumValueDescriptorProto $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <value> | |
* | |
* @return \google\protobuf\EnumValueDescriptorProto[] | |
*/ | |
public function getValueList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <value> | |
* | |
* @param \google\protobuf\EnumValueDescriptorProto $value | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function addValue(\google\protobuf\EnumValueDescriptorProto $value){ | |
return $this->_add(2, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\EnumOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\EnumOptions $value | |
* @return \google\protobuf\EnumDescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\EnumOptions $value){ | |
return $this->_set(3, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class EnumValueDescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumValueDescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional number = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "number"; | |
$f->nameOrig = "number"; | |
$f->type = 5; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional .google.protobuf.EnumValueOptions options = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\EnumValueOptions"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var int */ | |
public $number = null; | |
/** @var \google\protobuf\EnumValueOptions */ | |
public $options = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <number> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNumber(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <number> value | |
* | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function clearNumber(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <number> value | |
* | |
* @return int | |
*/ | |
public function getNumber(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <number> value | |
* | |
* @param int $value | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function setNumber( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\EnumValueOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\EnumValueOptions $value | |
* @return \google\protobuf\EnumValueDescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\EnumValueOptions $value){ | |
return $this->_set(3, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class ServiceDescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\ServiceDescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.MethodDescriptorProto method = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "method"; | |
$f->nameOrig = "method"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\MethodDescriptorProto"; | |
$descriptor->addField($f); | |
// optional .google.protobuf.ServiceOptions options = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\ServiceOptions"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var \google\protobuf\MethodDescriptorProto[] */ | |
public $method = array(); | |
/** @var \google\protobuf\ServiceOptions */ | |
public $options = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <method> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasMethod(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <method> value | |
* | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function clearMethod(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <method> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function getMethod($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <method> value | |
* | |
* @param \google\protobuf\MethodDescriptorProto $value | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function setMethod(\google\protobuf\MethodDescriptorProto $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <method> | |
* | |
* @return \google\protobuf\MethodDescriptorProto[] | |
*/ | |
public function getMethodList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <method> | |
* | |
* @param \google\protobuf\MethodDescriptorProto $value | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function addMethod(\google\protobuf\MethodDescriptorProto $value){ | |
return $this->_add(2, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\ServiceOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\ServiceOptions $value | |
* @return \google\protobuf\ServiceDescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\ServiceOptions $value){ | |
return $this->_set(3, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class MethodDescriptorProto extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\MethodDescriptorProto"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional input_type = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "input_type"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional output_type = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "output_type"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional .google.protobuf.MethodOptions options = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "options"; | |
$f->nameOrig = "options"; | |
$f->type = 11; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\MethodOptions"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var string */ | |
public $input_type = null; | |
/** @var string */ | |
public $output_type = null; | |
/** @var \google\protobuf\MethodOptions */ | |
public $options = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <input_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasInputType(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <input_type> value | |
* | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function clearInputType(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <input_type> value | |
* | |
* @return string | |
*/ | |
public function getInputType(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <input_type> value | |
* | |
* @param string $value | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function setInputType( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <output_type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOutputType(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <output_type> value | |
* | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function clearOutputType(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <output_type> value | |
* | |
* @return string | |
*/ | |
public function getOutputType(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <output_type> value | |
* | |
* @param string $value | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function setOutputType( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <options> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptions(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <options> value | |
* | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function clearOptions(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <options> value | |
* | |
* @return \google\protobuf\MethodOptions | |
*/ | |
public function getOptions(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <options> value | |
* | |
* @param \google\protobuf\MethodOptions $value | |
* @return \google\protobuf\MethodDescriptorProto | |
*/ | |
public function setOptions(\google\protobuf\MethodOptions $value){ | |
return $this->_set(4, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class FileOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FileOptions"); | |
// optional java_package = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "java_package"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional java_outer_classname = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "java_outer_classname"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional java_multiple_files = 10 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 10; | |
$f->name = "java_multiple_files"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// optional java_generate_equals_and_hash = 20 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 20; | |
$f->name = "java_generate_equals_and_hash"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 9; | |
$f->name = "optimize_for"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\FileOptions\OptimizeMode"; | |
$f->default = "SPEED"; | |
$descriptor->addField($f); | |
// optional cc_generic_services = 16 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 16; | |
$f->name = "cc_generic_services"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// optional java_generic_services = 17 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 17; | |
$f->name = "java_generic_services"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// optional py_generic_services = 18 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 18; | |
$f->name = "py_generic_services"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $java_package = null; | |
/** @var string */ | |
public $java_outer_classname = null; | |
/** @var boolean */ | |
public $java_multiple_files = true; | |
/** @var boolean */ | |
public $java_generate_equals_and_hash = true; | |
/** @var int - \google\protobuf\FileOptions\OptimizeMode */ | |
public $optimize_for = "SPEED"; | |
/** @var boolean */ | |
public $cc_generic_services = true; | |
/** @var boolean */ | |
public $java_generic_services = true; | |
/** @var boolean */ | |
public $py_generic_services = true; | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <java_package> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasJavaPackage(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <java_package> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearJavaPackage(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <java_package> value | |
* | |
* @return string | |
*/ | |
public function getJavaPackage(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <java_package> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setJavaPackage( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <java_outer_classname> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasJavaOuterClassname(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <java_outer_classname> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearJavaOuterClassname(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <java_outer_classname> value | |
* | |
* @return string | |
*/ | |
public function getJavaOuterClassname(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <java_outer_classname> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setJavaOuterClassname( $value){ | |
return $this->_set(8, $value); | |
} | |
/** | |
* Check if <java_multiple_files> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasJavaMultipleFiles(){ | |
return $this->_has(10); | |
} | |
/** | |
* Clear <java_multiple_files> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearJavaMultipleFiles(){ | |
return $this->_clear(10); | |
} | |
/** | |
* Get <java_multiple_files> value | |
* | |
* @return boolean | |
*/ | |
public function getJavaMultipleFiles(){ | |
return $this->_get(10); | |
} | |
/** | |
* Set <java_multiple_files> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setJavaMultipleFiles( $value){ | |
return $this->_set(10, $value); | |
} | |
/** | |
* Check if <java_generate_equals_and_hash> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasJavaGenerateEqualsAndHash(){ | |
return $this->_has(20); | |
} | |
/** | |
* Clear <java_generate_equals_and_hash> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearJavaGenerateEqualsAndHash(){ | |
return $this->_clear(20); | |
} | |
/** | |
* Get <java_generate_equals_and_hash> value | |
* | |
* @return boolean | |
*/ | |
public function getJavaGenerateEqualsAndHash(){ | |
return $this->_get(20); | |
} | |
/** | |
* Set <java_generate_equals_and_hash> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setJavaGenerateEqualsAndHash( $value){ | |
return $this->_set(20, $value); | |
} | |
/** | |
* Check if <optimize_for> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasOptimizeFor(){ | |
return $this->_has(9); | |
} | |
/** | |
* Clear <optimize_for> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearOptimizeFor(){ | |
return $this->_clear(9); | |
} | |
/** | |
* Get <optimize_for> value | |
* | |
* @return int - \google\protobuf\FileOptions\OptimizeMode | |
*/ | |
public function getOptimizeFor(){ | |
return $this->_get(9); | |
} | |
/** | |
* Set <optimize_for> value | |
* | |
* @param int - \google\protobuf\FileOptions\OptimizeMode $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setOptimizeFor( $value){ | |
return $this->_set(9, $value); | |
} | |
/** | |
* Check if <cc_generic_services> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasCcGenericServices(){ | |
return $this->_has(16); | |
} | |
/** | |
* Clear <cc_generic_services> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearCcGenericServices(){ | |
return $this->_clear(16); | |
} | |
/** | |
* Get <cc_generic_services> value | |
* | |
* @return boolean | |
*/ | |
public function getCcGenericServices(){ | |
return $this->_get(16); | |
} | |
/** | |
* Set <cc_generic_services> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setCcGenericServices( $value){ | |
return $this->_set(16, $value); | |
} | |
/** | |
* Check if <java_generic_services> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasJavaGenericServices(){ | |
return $this->_has(17); | |
} | |
/** | |
* Clear <java_generic_services> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearJavaGenericServices(){ | |
return $this->_clear(17); | |
} | |
/** | |
* Get <java_generic_services> value | |
* | |
* @return boolean | |
*/ | |
public function getJavaGenericServices(){ | |
return $this->_get(17); | |
} | |
/** | |
* Set <java_generic_services> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setJavaGenericServices( $value){ | |
return $this->_set(17, $value); | |
} | |
/** | |
* Check if <py_generic_services> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPyGenericServices(){ | |
return $this->_has(18); | |
} | |
/** | |
* Clear <py_generic_services> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearPyGenericServices(){ | |
return $this->_clear(18); | |
} | |
/** | |
* Get <py_generic_services> value | |
* | |
* @return boolean | |
*/ | |
public function getPyGenericServices(){ | |
return $this->_get(18); | |
} | |
/** | |
* Set <py_generic_services> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setPyGenericServices( $value){ | |
return $this->_set(18, $value); | |
} | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\FileOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf\FileOptions { | |
class OptimizeMode { | |
const SPEED = 1; | |
const CODE_SIZE = 2; | |
const LITE_RUNTIME = 3; | |
} | |
} | |
namespace google\protobuf { | |
class MessageOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\MessageOptions"); | |
// optional message_set_wire_format = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "message_set_wire_format"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// optional no_standard_descriptor_accessor = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "no_standard_descriptor_accessor"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var boolean */ | |
public $message_set_wire_format = true; | |
/** @var boolean */ | |
public $no_standard_descriptor_accessor = true; | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <message_set_wire_format> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasMessageSetWireFormat(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <message_set_wire_format> value | |
* | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function clearMessageSetWireFormat(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <message_set_wire_format> value | |
* | |
* @return boolean | |
*/ | |
public function getMessageSetWireFormat(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <message_set_wire_format> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function setMessageSetWireFormat( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <no_standard_descriptor_accessor> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNoStandardDescriptorAccessor(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <no_standard_descriptor_accessor> value | |
* | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function clearNoStandardDescriptorAccessor(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <no_standard_descriptor_accessor> value | |
* | |
* @return boolean | |
*/ | |
public function getNoStandardDescriptorAccessor(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <no_standard_descriptor_accessor> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function setNoStandardDescriptorAccessor( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\MessageOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class FieldOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\FieldOptions"); | |
// optional .google.protobuf.FieldOptions.CType ctype = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "ctype"; | |
$f->nameOrig = "ctype"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = "\google\protobuf\FieldOptions\CType"; | |
$f->default = "STRING"; | |
$descriptor->addField($f); | |
// optional packed = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "packed"; | |
$f->nameOrig = "packed"; | |
$f->type = 8; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional deprecated = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "deprecated"; | |
$f->nameOrig = "deprecated"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = true; | |
$descriptor->addField($f); | |
// optional experimental_map_key = 9 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 9; | |
$f->name = "experimental_map_key"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var int - \google\protobuf\FieldOptions\CType */ | |
public $ctype = "STRING"; | |
/** @var boolean */ | |
public $packed = null; | |
/** @var boolean */ | |
public $deprecated = true; | |
/** @var string */ | |
public $experimental_map_key = null; | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <ctype> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasCtype(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <ctype> value | |
* | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function clearCtype(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <ctype> value | |
* | |
* @return int - \google\protobuf\FieldOptions\CType | |
*/ | |
public function getCtype(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <ctype> value | |
* | |
* @param int - \google\protobuf\FieldOptions\CType $value | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function setCtype( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <packed> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPacked(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <packed> value | |
* | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function clearPacked(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <packed> value | |
* | |
* @return boolean | |
*/ | |
public function getPacked(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <packed> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function setPacked( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <deprecated> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDeprecated(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <deprecated> value | |
* | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function clearDeprecated(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <deprecated> value | |
* | |
* @return boolean | |
*/ | |
public function getDeprecated(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <deprecated> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function setDeprecated( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <experimental_map_key> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasExperimentalMapKey(){ | |
return $this->_has(9); | |
} | |
/** | |
* Clear <experimental_map_key> value | |
* | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function clearExperimentalMapKey(){ | |
return $this->_clear(9); | |
} | |
/** | |
* Get <experimental_map_key> value | |
* | |
* @return string | |
*/ | |
public function getExperimentalMapKey(){ | |
return $this->_get(9); | |
} | |
/** | |
* Set <experimental_map_key> value | |
* | |
* @param string $value | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function setExperimentalMapKey( $value){ | |
return $this->_set(9, $value); | |
} | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\FieldOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf\FieldOptions { | |
class CType { | |
const STRING = 0; | |
const CORD = 1; | |
const STRING_PIECE = 2; | |
} | |
} | |
namespace google\protobuf { | |
class EnumOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumOptions"); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\EnumOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\EnumOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\EnumOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class EnumValueOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\EnumValueOptions"); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\EnumValueOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\EnumValueOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\EnumValueOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class ServiceOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\ServiceOptions"); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\ServiceOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\ServiceOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\ServiceOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class MethodOptions extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\MethodOptions"); | |
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 999; | |
$f->name = "uninterpreted_option"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\UninterpretedOption[] */ | |
public $uninterpreted_option = array(); | |
/** | |
* Check if <uninterpreted_option> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUninterpretedOption(){ | |
return $this->_has(999); | |
} | |
/** | |
* Clear <uninterpreted_option> value | |
* | |
* @return \google\protobuf\MethodOptions | |
*/ | |
public function clearUninterpretedOption(){ | |
return $this->_clear(999); | |
} | |
/** | |
* Get <uninterpreted_option> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function getUninterpretedOption($idx = NULL){ | |
return $this->_get(999, $idx); | |
} | |
/** | |
* Set <uninterpreted_option> value | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\MethodOptions | |
*/ | |
public function setUninterpretedOption(\google\protobuf\UninterpretedOption $value, $idx = NULL){ | |
return $this->_set(999, $value, $idx); | |
} | |
/** | |
* Get all elements of <uninterpreted_option> | |
* | |
* @return \google\protobuf\UninterpretedOption[] | |
*/ | |
public function getUninterpretedOptionList(){ | |
return $this->_get(999); | |
} | |
/** | |
* Add a new element to <uninterpreted_option> | |
* | |
* @param \google\protobuf\UninterpretedOption $value | |
* @return \google\protobuf\MethodOptions | |
*/ | |
public function addUninterpretedOption(\google\protobuf\UninterpretedOption $value){ | |
return $this->_add(999, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class UninterpretedOption extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\UninterpretedOption"); | |
// repeated .google.protobuf.UninterpretedOption.NamePart name = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\UninterpretedOption\NamePart"; | |
$descriptor->addField($f); | |
// optional identifier_value = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "identifier_value"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional positive_int_value = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "positive_int_value"; | |
$f->type = 4; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional negative_int_value = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "negative_int_value"; | |
$f->type = 3; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional double_value = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "double_value"; | |
$f->type = 1; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional string_value = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "string_value"; | |
$f->type = 12; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional aggregate_value = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "aggregate_value"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\UninterpretedOption\NamePart[] */ | |
public $name = array(); | |
/** @var string */ | |
public $identifier_value = null; | |
/** @var int */ | |
public $positive_int_value = null; | |
/** @var int */ | |
public $negative_int_value = null; | |
/** @var float */ | |
public $double_value = null; | |
/** @var string */ | |
public $string_value = null; | |
/** @var string */ | |
public $aggregate_value = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearName(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <name> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\UninterpretedOption\NamePart | |
*/ | |
public function getName($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param \google\protobuf\UninterpretedOption\NamePart $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setName(\google\protobuf\UninterpretedOption\NamePart $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <name> | |
* | |
* @return \google\protobuf\UninterpretedOption\NamePart[] | |
*/ | |
public function getNameList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <name> | |
* | |
* @param \google\protobuf\UninterpretedOption\NamePart $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function addName(\google\protobuf\UninterpretedOption\NamePart $value){ | |
return $this->_add(2, $value); | |
} | |
/** | |
* Check if <identifier_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasIdentifierValue(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <identifier_value> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearIdentifierValue(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <identifier_value> value | |
* | |
* @return string | |
*/ | |
public function getIdentifierValue(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <identifier_value> value | |
* | |
* @param string $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setIdentifierValue( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <positive_int_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPositiveIntValue(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <positive_int_value> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearPositiveIntValue(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <positive_int_value> value | |
* | |
* @return int | |
*/ | |
public function getPositiveIntValue(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <positive_int_value> value | |
* | |
* @param int $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setPositiveIntValue( $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <negative_int_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNegativeIntValue(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <negative_int_value> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearNegativeIntValue(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <negative_int_value> value | |
* | |
* @return int | |
*/ | |
public function getNegativeIntValue(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <negative_int_value> value | |
* | |
* @param int $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setNegativeIntValue( $value){ | |
return $this->_set(5, $value); | |
} | |
/** | |
* Check if <double_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDoubleValue(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <double_value> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearDoubleValue(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <double_value> value | |
* | |
* @return float | |
*/ | |
public function getDoubleValue(){ | |
return $this->_get(6); | |
} | |
/** | |
* Set <double_value> value | |
* | |
* @param float $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setDoubleValue( $value){ | |
return $this->_set(6, $value); | |
} | |
/** | |
* Check if <string_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasStringValue(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <string_value> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearStringValue(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <string_value> value | |
* | |
* @return string | |
*/ | |
public function getStringValue(){ | |
return $this->_get(7); | |
} | |
/** | |
* Set <string_value> value | |
* | |
* @param string $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setStringValue( $value){ | |
return $this->_set(7, $value); | |
} | |
/** | |
* Check if <aggregate_value> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasAggregateValue(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <aggregate_value> value | |
* | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function clearAggregateValue(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <aggregate_value> value | |
* | |
* @return string | |
*/ | |
public function getAggregateValue(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <aggregate_value> value | |
* | |
* @param string $value | |
* @return \google\protobuf\UninterpretedOption | |
*/ | |
public function setAggregateValue( $value){ | |
return $this->_set(8, $value); | |
} | |
} | |
} | |
namespace google\protobuf\UninterpretedOption { | |
class NamePart extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\UninterpretedOption\NamePart"); | |
// required name_part = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name_part"; | |
$f->type = 9; | |
$f->rule = 2; | |
$descriptor->addField($f); | |
// required is_extension = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "is_extension"; | |
$f->type = 8; | |
$f->rule = 2; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name_part = null; | |
/** @var boolean */ | |
public $is_extension = null; | |
/** | |
* Check if <name_part> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNamePart(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name_part> value | |
* | |
* @return \google\protobuf\UninterpretedOption\NamePart | |
*/ | |
public function clearNamePart(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name_part> value | |
* | |
* @return string | |
*/ | |
public function getNamePart(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name_part> value | |
* | |
* @param string $value | |
* @return \google\protobuf\UninterpretedOption\NamePart | |
*/ | |
public function setNamePart( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <is_extension> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasIsExtension(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <is_extension> value | |
* | |
* @return \google\protobuf\UninterpretedOption\NamePart | |
*/ | |
public function clearIsExtension(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <is_extension> value | |
* | |
* @return boolean | |
*/ | |
public function getIsExtension(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <is_extension> value | |
* | |
* @param boolean $value | |
* @return \google\protobuf\UninterpretedOption\NamePart | |
*/ | |
public function setIsExtension( $value){ | |
return $this->_set(2, $value); | |
} | |
} | |
} | |
namespace google\protobuf { | |
class SourceCodeInfo extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\SourceCodeInfo"); | |
// repeated .google.protobuf.SourceCodeInfo.Location location = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "location"; | |
$f->nameOrig = "location"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\SourceCodeInfo\Location"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var \google\protobuf\SourceCodeInfo\Location[] */ | |
public $location = array(); | |
/** | |
* Check if <location> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasLocation(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <location> value | |
* | |
* @return \google\protobuf\SourceCodeInfo | |
*/ | |
public function clearLocation(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <location> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function getLocation($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <location> value | |
* | |
* @param \google\protobuf\SourceCodeInfo\Location $value | |
* @return \google\protobuf\SourceCodeInfo | |
*/ | |
public function setLocation(\google\protobuf\SourceCodeInfo\Location $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <location> | |
* | |
* @return \google\protobuf\SourceCodeInfo\Location[] | |
*/ | |
public function getLocationList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <location> | |
* | |
* @param \google\protobuf\SourceCodeInfo\Location $value | |
* @return \google\protobuf\SourceCodeInfo | |
*/ | |
public function addLocation(\google\protobuf\SourceCodeInfo\Location $value){ | |
return $this->_add(1, $value); | |
} | |
} | |
} | |
namespace google\protobuf\SourceCodeInfo { | |
class Location extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\SourceCodeInfo\Location"); | |
// repeated path = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "path"; | |
$f->nameOrig = "path"; | |
$f->type = 5; | |
$f->rule = 3; | |
$descriptor->addField($f); | |
// repeated span = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "span"; | |
$f->nameOrig = "span"; | |
$f->type = 5; | |
$f->rule = 3; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var int[] */ | |
public $path = array(); | |
/** @var int[] */ | |
public $span = array(); | |
/** | |
* Check if <path> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPath(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <path> value | |
* | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function clearPath(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <path> value | |
* | |
* @param int $idx | |
* @return int | |
*/ | |
public function getPath($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <path> value | |
* | |
* @param int $value | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function setPath( $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <path> | |
* | |
* @return int[] | |
*/ | |
public function getPathList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <path> | |
* | |
* @param int $value | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function addPath( $value){ | |
return $this->_add(1, $value); | |
} | |
/** | |
* Check if <span> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSpan(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <span> value | |
* | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function clearSpan(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <span> value | |
* | |
* @param int $idx | |
* @return int | |
*/ | |
public function getSpan($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <span> value | |
* | |
* @param int $value | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function setSpan( $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <span> | |
* | |
* @return int[] | |
*/ | |
public function getSpanList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <span> | |
* | |
* @param int $value | |
* @return \google\protobuf\SourceCodeInfo\Location | |
*/ | |
public function addSpan( $value){ | |
return $this->_add(2, $value); | |
} | |
} | |
} | |
// Protocol Buffers - Google's data interchange format | |
// Copyright 2008 Google Inc. All rights reserved. | |
// http://code.google.com/p/protobuf/ | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions are | |
// met: | |
// | |
// * Redistributions of source code must retain the above copyright | |
// notice, this list of conditions and the following disclaimer. | |
// * Redistributions in binary form must reproduce the above | |
// copyright notice, this list of conditions and the following disclaimer | |
// in the documentation and/or other materials provided with the | |
// distribution. | |
// * Neither the name of Google Inc. nor the names of its | |
// contributors may be used to endorse or promote products derived from | |
// this software without specific prior written permission. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// Author: kenton@google.com (Kenton Varda) | |
// Based on original Protocol Buffers design by | |
// Sanjay Ghemawat, Jeff Dean, and others. | |
// | |
// The messages in this file describe the definitions found in .proto files. | |
// A valid .proto file can be translated directly to a FileDescriptorProto | |
// without any other information (e.g. without reading its imports). | |
package google.protobuf; | |
option java_package = "com.google.protobuf"; | |
option java_outer_classname = "DescriptorProtos"; | |
// descriptor.proto must be optimized for speed because reflection-based | |
// algorithms don't work during bootstrapping. | |
option optimize_for = SPEED; | |
// The protocol compiler can output a FileDescriptorSet containing the .proto | |
// files it parses. | |
message FileDescriptorSet { | |
repeated FileDescriptorProto file = 1; | |
} | |
// Describes a complete .proto file. | |
message FileDescriptorProto { | |
optional string name = 1; // file name, relative to root of source tree | |
optional string package = 2; // e.g. "foo", "foo.bar", etc. | |
// Names of files imported by this file. | |
repeated string dependency = 3; | |
// All top-level definitions in this file. | |
repeated DescriptorProto message_type = 4; | |
repeated EnumDescriptorProto enum_type = 5; | |
repeated ServiceDescriptorProto service = 6; | |
repeated FieldDescriptorProto extension = 7; | |
optional FileOptions options = 8; | |
// This field contains optional information about the original source code. | |
// You may safely remove this entire field whithout harming runtime | |
// functionality of the descriptors -- the information is needed only by | |
// development tools. | |
optional SourceCodeInfo source_code_info = 9; | |
} | |
// Describes a message type. | |
message DescriptorProto { | |
optional string name = 1; | |
repeated FieldDescriptorProto field = 2; | |
repeated FieldDescriptorProto extension = 6; | |
repeated DescriptorProto nested_type = 3; | |
repeated EnumDescriptorProto enum_type = 4; | |
message ExtensionRange { | |
optional int32 start = 1; | |
optional int32 end = 2; | |
} | |
repeated ExtensionRange extension_range = 5; | |
optional MessageOptions options = 7; | |
} | |
// Describes a field within a message. | |
message FieldDescriptorProto { | |
enum Type { | |
// 0 is reserved for errors. | |
// Order is weird for historical reasons. | |
TYPE_DOUBLE = 1; | |
TYPE_FLOAT = 2; | |
TYPE_INT64 = 3; // Not ZigZag encoded. Negative numbers | |
// take 10 bytes. Use TYPE_SINT64 if negative | |
// values are likely. | |
TYPE_UINT64 = 4; | |
TYPE_INT32 = 5; // Not ZigZag encoded. Negative numbers | |
// take 10 bytes. Use TYPE_SINT32 if negative | |
// values are likely. | |
TYPE_FIXED64 = 6; | |
TYPE_FIXED32 = 7; | |
TYPE_BOOL = 8; | |
TYPE_STRING = 9; | |
TYPE_GROUP = 10; // Tag-delimited aggregate. | |
TYPE_MESSAGE = 11; // Length-delimited aggregate. | |
// New in version 2. | |
TYPE_BYTES = 12; | |
TYPE_UINT32 = 13; | |
TYPE_ENUM = 14; | |
TYPE_SFIXED32 = 15; | |
TYPE_SFIXED64 = 16; | |
TYPE_SINT32 = 17; // Uses ZigZag encoding. | |
TYPE_SINT64 = 18; // Uses ZigZag encoding. | |
}; | |
enum Label { | |
// 0 is reserved for errors | |
LABEL_OPTIONAL = 1; | |
LABEL_REQUIRED = 2; | |
LABEL_REPEATED = 3; | |
// TODO(sanjay): Should we add LABEL_MAP? | |
}; | |
optional string name = 1; | |
optional int32 number = 3; | |
optional Label label = 4; | |
// If type_name is set, this need not be set. If both this and type_name | |
// are set, this must be either TYPE_ENUM or TYPE_MESSAGE. | |
optional Type type = 5; | |
// For message and enum types, this is the name of the type. If the name | |
// starts with a '.', it is fully-qualified. Otherwise, C++-like scoping | |
// rules are used to find the type (i.e. first the nested types within this | |
// message are searched, then within the parent, on up to the root | |
// namespace). | |
optional string type_name = 6; | |
// For extensions, this is the name of the type being extended. It is | |
// resolved in the same manner as type_name. | |
optional string extendee = 2; | |
// For numeric types, contains the original text representation of the value. | |
// For booleans, "true" or "false". | |
// For strings, contains the default text contents (not escaped in any way). | |
// For bytes, contains the C escaped value. All bytes >= 128 are escaped. | |
// TODO(kenton): Base-64 encode? | |
optional string default_value = 7; | |
optional FieldOptions options = 8; | |
} | |
// Describes an enum type. | |
message EnumDescriptorProto { | |
optional string name = 1; | |
repeated EnumValueDescriptorProto value = 2; | |
optional EnumOptions options = 3; | |
} | |
// Describes a value within an enum. | |
message EnumValueDescriptorProto { | |
optional string name = 1; | |
optional int32 number = 2; | |
optional EnumValueOptions options = 3; | |
} | |
// Describes a service. | |
message ServiceDescriptorProto { | |
optional string name = 1; | |
repeated MethodDescriptorProto method = 2; | |
optional ServiceOptions options = 3; | |
} | |
// Describes a method of a service. | |
message MethodDescriptorProto { | |
optional string name = 1; | |
// Input and output type names. These are resolved in the same way as | |
// FieldDescriptorProto.type_name, but must refer to a message type. | |
optional string input_type = 2; | |
optional string output_type = 3; | |
optional MethodOptions options = 4; | |
} | |
// =================================================================== | |
// Options | |
// Each of the definitions above may have "options" attached. These are | |
// just annotations which may cause code to be generated slightly differently | |
// or may contain hints for code that manipulates protocol messages. | |
// | |
// Clients may define custom options as extensions of the *Options messages. | |
// These extensions may not yet be known at parsing time, so the parser cannot | |
// store the values in them. Instead it stores them in a field in the *Options | |
// message called uninterpreted_option. This field must have the same name | |
// across all *Options messages. We then use this field to populate the | |
// extensions when we build a descriptor, at which point all protos have been | |
// parsed and so all extensions are known. | |
// | |
// Extension numbers for custom options may be chosen as follows: | |
// * For options which will only be used within a single application or | |
// organization, or for experimental options, use field numbers 50000 | |
// through 99999. It is up to you to ensure that you do not use the | |
// same number for multiple options. | |
// * For options which will be published and used publicly by multiple | |
// independent entities, e-mail kenton@google.com to reserve extension | |
// numbers. Simply tell me how many you need and I'll send you back a | |
// set of numbers to use -- there's no need to explain how you intend to | |
// use them. If this turns out to be popular, a web service will be set up | |
// to automatically assign option numbers. | |
message FileOptions { | |
// Sets the Java package where classes generated from this .proto will be | |
// placed. By default, the proto package is used, but this is often | |
// inappropriate because proto packages do not normally start with backwards | |
// domain names. | |
optional string java_package = 1; | |
// If set, all the classes from the .proto file are wrapped in a single | |
// outer class with the given name. This applies to both Proto1 | |
// (equivalent to the old "--one_java_file" option) and Proto2 (where | |
// a .proto always translates to a single class, but you may want to | |
// explicitly choose the class name). | |
optional string java_outer_classname = 8; | |
// If set true, then the Java code generator will generate a separate .java | |
// file for each top-level message, enum, and service defined in the .proto | |
// file. Thus, these types will *not* be nested inside the outer class | |
// named by java_outer_classname. However, the outer class will still be | |
// generated to contain the file's getDescriptor() method as well as any | |
// top-level extensions defined in the file. | |
optional bool java_multiple_files = 10 [default=false]; | |
// If set true, then the Java code generator will generate equals() and | |
// hashCode() methods for all messages defined in the .proto file. This is | |
// purely a speed optimization, as the AbstractMessage base class includes | |
// reflection-based implementations of these methods. | |
optional bool java_generate_equals_and_hash = 20 [default=false]; | |
// Generated classes can be optimized for speed or code size. | |
enum OptimizeMode { | |
SPEED = 1; // Generate complete code for parsing, serialization, | |
// etc. | |
CODE_SIZE = 2; // Use ReflectionOps to implement these methods. | |
LITE_RUNTIME = 3; // Generate code using MessageLite and the lite runtime. | |
} | |
optional OptimizeMode optimize_for = 9 [default=SPEED]; | |
// Should generic services be generated in each language? "Generic" services | |
// are not specific to any particular RPC system. They are generated by the | |
// main code generators in each language (without additional plugins). | |
// Generic services were the only kind of service generation supported by | |
// early versions of proto2. | |
// | |
// Generic services are now considered deprecated in favor of using plugins | |
// that generate code specific to your particular RPC system. Therefore, | |
// these default to false. Old code which depends on generic services should | |
// explicitly set them to true. | |
optional bool cc_generic_services = 16 [default=false]; | |
optional bool java_generic_services = 17 [default=false]; | |
optional bool py_generic_services = 18 [default=false]; | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
message MessageOptions { | |
// Set true to use the old proto1 MessageSet wire format for extensions. | |
// This is provided for backwards-compatibility with the MessageSet wire | |
// format. You should not use this for any other reason: It's less | |
// efficient, has fewer features, and is more complicated. | |
// | |
// The message must be defined exactly as follows: | |
// message Foo { | |
// option message_set_wire_format = true; | |
// extensions 4 to max; | |
// } | |
// Note that the message cannot have any defined fields; MessageSets only | |
// have extensions. | |
// | |
// All extensions of your type must be singular messages; e.g. they cannot | |
// be int32s, enums, or repeated messages. | |
// | |
// Because this is an option, the above two restrictions are not enforced by | |
// the protocol compiler. | |
optional bool message_set_wire_format = 1 [default=false]; | |
// Disables the generation of the standard "descriptor()" accessor, which can | |
// conflict with a field of the same name. This is meant to make migration | |
// from proto1 easier; new code should avoid fields named "descriptor". | |
optional bool no_standard_descriptor_accessor = 2 [default=false]; | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
message FieldOptions { | |
// The ctype option instructs the C++ code generator to use a different | |
// representation of the field than it normally would. See the specific | |
// options below. This option is not yet implemented in the open source | |
// release -- sorry, we'll try to include it in a future version! | |
optional CType ctype = 1 [default = STRING]; | |
enum CType { | |
// Default mode. | |
STRING = 0; | |
CORD = 1; | |
STRING_PIECE = 2; | |
} | |
// The packed option can be enabled for repeated primitive fields to enable | |
// a more efficient representation on the wire. Rather than repeatedly | |
// writing the tag and type for each element, the entire array is encoded as | |
// a single length-delimited blob. | |
optional bool packed = 2; | |
// Is this field deprecated? | |
// Depending on the target platform, this can emit Deprecated annotations | |
// for accessors, or it will be completely ignored; in the very least, this | |
// is a formalization for deprecating fields. | |
optional bool deprecated = 3 [default=false]; | |
// EXPERIMENTAL. DO NOT USE. | |
// For "map" fields, the name of the field in the enclosed type that | |
// is the key for this map. For example, suppose we have: | |
// message Item { | |
// required string name = 1; | |
// required string value = 2; | |
// } | |
// message Config { | |
// repeated Item items = 1 [experimental_map_key="name"]; | |
// } | |
// In this situation, the map key for Item will be set to "name". | |
// TODO: Fully-implement this, then remove the "experimental_" prefix. | |
optional string experimental_map_key = 9; | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
message EnumOptions { | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
message EnumValueOptions { | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
message ServiceOptions { | |
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC | |
// framework. We apologize for hoarding these numbers to ourselves, but | |
// we were already using them long before we decided to release Protocol | |
// Buffers. | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
message MethodOptions { | |
// Note: Field numbers 1 through 32 are reserved for Google's internal RPC | |
// framework. We apologize for hoarding these numbers to ourselves, but | |
// we were already using them long before we decided to release Protocol | |
// Buffers. | |
// The parser stores options it doesn't recognize here. See above. | |
repeated UninterpretedOption uninterpreted_option = 999; | |
// Clients can define custom options in extensions of this message. See above. | |
extensions 1000 to max; | |
} | |
// A message representing a option the parser does not recognize. This only | |
// appears in options protos created by the compiler::Parser class. | |
// DescriptorPool resolves these when building Descriptor objects. Therefore, | |
// options protos in descriptor objects (e.g. returned by Descriptor::options(), | |
// or produced by Descriptor::CopyTo()) will never have UninterpretedOptions | |
// in them. | |
message UninterpretedOption { | |
// The name of the uninterpreted option. Each string represents a segment in | |
// a dot-separated name. is_extension is true iff a segment represents an | |
// extension (denoted with parentheses in options specs in .proto files). | |
// E.g.,{ ["foo", false], ["bar.baz", true], ["qux", false] } represents | |
// "foo.(bar.baz).qux". | |
message NamePart { | |
required string name_part = 1; | |
required bool is_extension = 2; | |
} | |
repeated NamePart name = 2; | |
// The value of the uninterpreted option, in whatever type the tokenizer | |
// identified it as during parsing. Exactly one of these should be set. | |
optional string identifier_value = 3; | |
optional uint64 positive_int_value = 4; | |
optional int64 negative_int_value = 5; | |
optional double double_value = 6; | |
optional bytes string_value = 7; | |
optional string aggregate_value = 8; | |
} | |
// =================================================================== | |
// Optional source code info | |
// Encapsulates information about the original source file from which a | |
// FileDescriptorProto was generated. | |
message SourceCodeInfo { | |
// A Location identifies a piece of source code in a .proto file which | |
// corresponds to a particular definition. This information is intended | |
// to be useful to IDEs, code indexers, documentation generators, and similar | |
// tools. | |
// | |
// For example, say we have a file like: | |
// message Foo { | |
// optional string foo = 1; | |
// } | |
// Let's look at just the field definition: | |
// optional string foo = 1; | |
// ^ ^^ ^^ ^ ^^^ | |
// a bc de f ghi | |
// We have the following locations: | |
// span path represents | |
// [a,i) [ 4, 0, 2, 0 ] The whole field definition. | |
// [a,b) [ 4, 0, 2, 0, 4 ] The label (optional). | |
// [c,d) [ 4, 0, 2, 0, 5 ] The type (string). | |
// [e,f) [ 4, 0, 2, 0, 1 ] The name (foo). | |
// [g,h) [ 4, 0, 2, 0, 3 ] The number (1). | |
// | |
// Notes: | |
// - A location may refer to a repeated field itself (i.e. not to any | |
// particular index within it). This is used whenever a set of elements are | |
// logically enclosed in a single code segment. For example, an entire | |
// extend block (possibly containing multiple extension definitions) will | |
// have an outer location whose path refers to the "extensions" repeated | |
// field without an index. | |
// - Multiple locations may have the same path. This happens when a single | |
// logical declaration is spread out across multiple places. The most | |
// obvious example is the "extend" block again -- there may be multiple | |
// extend blocks in the same scope, each of which will have the same path. | |
// - A location's span is not always a subset of its parent's span. For | |
// example, the "extendee" of an extension declaration appears at the | |
// beginning of the "extend" block and is shared by all extensions within | |
// the block. | |
// - Just because a location's span is a subset of some other location's span | |
// does not mean that it is a descendent. For example, a "group" defines | |
// both a type and a field in a single declaration. Thus, the locations | |
// corresponding to the type and field and their components will overlap. | |
// - Code which tries to interpret locations should probably be designed to | |
// ignore those that it doesn't understand, as more types of locations could | |
// be recorded in the future. | |
repeated Location location = 1; | |
message Location { | |
// Identifies which part of the FileDescriptorProto was defined at this | |
// location. | |
// | |
// Each element is a field number or an index. They form a path from | |
// the root FileDescriptorProto to the place where the definition. For | |
// example, this path: | |
// [ 4, 3, 2, 7, 1 ] | |
// refers to: | |
// file.message_type(3) // 4, 3 | |
// .field(7) // 2, 7 | |
// .name() // 1 | |
// This is because FileDescriptorProto.message_type has field number 4: | |
// repeated DescriptorProto message_type = 4; | |
// and DescriptorProto.field has field number 2: | |
// repeated FieldDescriptorProto field = 2; | |
// and FieldDescriptorProto.name has field number 1: | |
// optional string name = 1; | |
// | |
// Thus, the above path gives the location of a field name. If we removed | |
// the last element: | |
// [ 4, 3, 2, 7 ] | |
// this path refers to the whole field declaration (from the beginning | |
// of the label to the terminating semicolon). | |
repeated int32 path = 1 [packed=true]; | |
// Always has exactly three or four elements: start line, start column, | |
// end line (optional, otherwise assumed same as start line), end column. | |
// These are packed into a single field for efficiency. Note that line | |
// and column numbers are zero-based -- typically you will want to add | |
// 1 to each before displaying to a user. | |
repeated int32 span = 2 [packed=true]; | |
// TODO(kenton): Record comments appearing before and after the | |
// declaration. | |
} | |
} | |
<?php | |
// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@ | |
// Source: php.proto | |
// Date: 2011-03-20 01:27:38 | |
namespace { | |
\google\protobuf\FileOptions::extension(function(){ | |
// optional php.namespace = 50002 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 50102; | |
$f->name = "json.namespace"; | |
$f->type = 9; | |
$f->rule = 1; | |
return $f; | |
}); | |
\google\protobuf\FileOptions::extension(function(){ | |
// optional php.suffix = 50003 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 50103; | |
$f->name = "json.suffix"; | |
$f->type = 9; | |
$f->rule = 1; | |
$f->default = ".pb.js"; | |
return $f; | |
}); | |
} | |
import "descriptor.proto"; | |
package json; | |
extend google.protobuf.FileOptions { | |
// Set the namespace (overrides package) | |
optional string namespace = 50102; | |
// Suffix for file names | |
optional string suffix = 50103 [default = ".pb.js"]; | |
} | |
//extend google.protobuf.MessageOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.FieldOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.EnumOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.EnumValueOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.ServiceOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.MethodOptions { | |
// | |
//} | |
<?php | |
// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@ | |
// Source: php.proto | |
// Date: 2011-03-20 01:27:38 | |
namespace { | |
\google\protobuf\FileOptions::extension(function(){ | |
// optional php.namespace = 50002 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 50002; | |
$f->name = "php.namespace"; | |
$f->type = 9; | |
$f->rule = 1; | |
return $f; | |
}); | |
\google\protobuf\FileOptions::extension(function(){ | |
// optional php.suffix = 50003 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 50003; | |
$f->name = "php.suffix"; | |
$f->type = 9; | |
$f->rule = 1; | |
$f->default = ".php"; | |
return $f; | |
}); | |
\google\protobuf\FileOptions::extension(function(){ | |
// optional php.multiple = 50004 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 50004; | |
$f->name = "php.multifile"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = false; | |
return $f; | |
}); | |
\google\protobuf\FileOptions::extension(function(){ | |
// optional php.generic_services = 50005 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 50005; | |
$f->name = "php.generic_services"; | |
$f->type = 8; | |
$f->rule = 1; | |
$f->default = false; | |
return $f; | |
}); | |
} | |
import "descriptor.proto"; | |
package php; | |
extend google.protobuf.FileOptions { | |
// Set the namespace (overrides package) | |
optional string namespace = 50002; | |
// Suffix for file names | |
optional string suffix = 50003 [default = ".php"]; | |
// Generate a file for each structure in the proto | |
optional bool multifile = 50004 [default = false]; | |
// Generate interfaces for service definitions | |
optional bool generic_services = 50005 [default = false]; | |
} | |
//extend google.protobuf.MessageOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.FieldOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.EnumOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.EnumValueOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.ServiceOptions { | |
// | |
//} | |
// | |
//extend google.protobuf.MethodOptions { | |
// | |
//} | |
<?php | |
// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@ | |
// Source: plugin.proto | |
// Date: 2011-03-20 01:27:33 | |
namespace google\protobuf\compiler { | |
class CodeGeneratorRequest extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\compiler\CodeGeneratorRequest"); | |
// repeated file_to_generate = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "file_to_generate"; | |
$f->type = 9; | |
$f->rule = 3; | |
$descriptor->addField($f); | |
// optional parameter = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "parameter"; | |
$f->nameOrig = "parameter"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.FileDescriptorProto proto_file = 15 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 15; | |
$f->name = "proto_file"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\FileDescriptorProto"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string[] */ | |
public $file_to_generate = array(); | |
/** @var string */ | |
public $parameter = null; | |
/** @var \google\protobuf\FileDescriptorProto[] */ | |
public $proto_file = array(); | |
/** | |
* Check if <file_to_generate> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasFileToGenerate(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <file_to_generate> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function clearFileToGenerate(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <file_to_generate> value | |
* | |
* @param int $idx | |
* @return string | |
*/ | |
public function getFileToGenerate($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <file_to_generate> value | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function setFileToGenerate( $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <file_to_generate> | |
* | |
* @return string[] | |
*/ | |
public function getFileToGenerateList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <file_to_generate> | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function addFileToGenerate( $value){ | |
return $this->_add(1, $value); | |
} | |
/** | |
* Check if <parameter> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasParameter(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <parameter> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function clearParameter(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <parameter> value | |
* | |
* @return string | |
*/ | |
public function getParameter(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <parameter> value | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function setParameter( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <proto_file> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasProtoFile(){ | |
return $this->_has(15); | |
} | |
/** | |
* Clear <proto_file> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function clearProtoFile(){ | |
return $this->_clear(15); | |
} | |
/** | |
* Get <proto_file> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\FileDescriptorProto | |
*/ | |
public function getProtoFile($idx = NULL){ | |
return $this->_get(15, $idx); | |
} | |
/** | |
* Set <proto_file> value | |
* | |
* @param \google\protobuf\FileDescriptorProto $value | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function setProtoFile(\google\protobuf\FileDescriptorProto $value, $idx = NULL){ | |
return $this->_set(15, $value, $idx); | |
} | |
/** | |
* Get all elements of <proto_file> | |
* | |
* @return \google\protobuf\FileDescriptorProto[] | |
*/ | |
public function getProtoFileList(){ | |
return $this->_get(15); | |
} | |
/** | |
* Add a new element to <proto_file> | |
* | |
* @param \google\protobuf\FileDescriptorProto $value | |
* @return \google\protobuf\compiler\CodeGeneratorRequest | |
*/ | |
public function addProtoFile(\google\protobuf\FileDescriptorProto $value){ | |
return $this->_add(15, $value); | |
} | |
} | |
} | |
namespace google\protobuf\compiler { | |
class CodeGeneratorResponse extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\compiler\CodeGeneratorResponse"); | |
// optional error = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "error"; | |
$f->nameOrig = "error"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .google.protobuf.compiler.CodeGeneratorResponse.File file = 15 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 15; | |
$f->name = "file"; | |
$f->nameOrig = "file"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = "\google\protobuf\compiler\CodeGeneratorResponse\File"; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $error = null; | |
/** @var \google\protobuf\compiler\CodeGeneratorResponse\File[] */ | |
public $file = array(); | |
/** | |
* Check if <error> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasError(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <error> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorResponse | |
*/ | |
public function clearError(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <error> value | |
* | |
* @return string | |
*/ | |
public function getError(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <error> value | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorResponse | |
*/ | |
public function setError( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <file> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasFile(){ | |
return $this->_has(15); | |
} | |
/** | |
* Clear <file> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorResponse | |
*/ | |
public function clearFile(){ | |
return $this->_clear(15); | |
} | |
/** | |
* Get <file> value | |
* | |
* @param int $idx | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function getFile($idx = NULL){ | |
return $this->_get(15, $idx); | |
} | |
/** | |
* Set <file> value | |
* | |
* @param \google\protobuf\compiler\CodeGeneratorResponse\File $value | |
* @return \google\protobuf\compiler\CodeGeneratorResponse | |
*/ | |
public function setFile(\google\protobuf\compiler\CodeGeneratorResponse\File $value, $idx = NULL){ | |
return $this->_set(15, $value, $idx); | |
} | |
/** | |
* Get all elements of <file> | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File[] | |
*/ | |
public function getFileList(){ | |
return $this->_get(15); | |
} | |
/** | |
* Add a new element to <file> | |
* | |
* @param \google\protobuf\compiler\CodeGeneratorResponse\File $value | |
* @return \google\protobuf\compiler\CodeGeneratorResponse | |
*/ | |
public function addFile(\google\protobuf\compiler\CodeGeneratorResponse\File $value){ | |
return $this->_add(15, $value); | |
} | |
} | |
} | |
namespace google\protobuf\compiler\CodeGeneratorResponse { | |
class File extends \DrSlump\Protobuf\Message { | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected static $__descriptor; | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
if (NULL !== $descriptor) { | |
self::$__descriptor = $descriptor; | |
return self::$__descriptor; | |
} | |
if (!self::$__descriptor) { | |
$descriptor = new \DrSlump\Protobuf\Descriptor("\google\protobuf\compiler\CodeGeneratorResponse\File"); | |
// optional name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->nameOrig = "name"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional insertion_point = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "insertion_point"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// optional content = 15 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 15; | |
$f->name = "content"; | |
$f->nameOrig = "content"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
self::$__descriptor = $descriptor; | |
} | |
return self::$__descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var string */ | |
public $insertion_point = null; | |
/** @var string */ | |
public $content = null; | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <insertion_point> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasInsertionPoint(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <insertion_point> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function clearInsertionPoint(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <insertion_point> value | |
* | |
* @return string | |
*/ | |
public function getInsertionPoint(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <insertion_point> value | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function setInsertionPoint( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <content> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasContent(){ | |
return $this->_has(15); | |
} | |
/** | |
* Clear <content> value | |
* | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function clearContent(){ | |
return $this->_clear(15); | |
} | |
/** | |
* Get <content> value | |
* | |
* @return string | |
*/ | |
public function getContent(){ | |
return $this->_get(15); | |
} | |
/** | |
* Set <content> value | |
* | |
* @param string $value | |
* @return \google\protobuf\compiler\CodeGeneratorResponse\File | |
*/ | |
public function setContent( $value){ | |
return $this->_set(15, $value); | |
} | |
} | |
} | |
// Protocol Buffers - Google's data interchange format | |
// Copyright 2008 Google Inc. All rights reserved. | |
// http://code.google.com/p/protobuf/ | |
// | |
// Redistribution and use in source and binary forms, with or without | |
// modification, are permitted provided that the following conditions are | |
// met: | |
// | |
// * Redistributions of source code must retain the above copyright | |
// notice, this list of conditions and the following disclaimer. | |
// * Redistributions in binary form must reproduce the above | |
// copyright notice, this list of conditions and the following disclaimer | |
// in the documentation and/or other materials provided with the | |
// distribution. | |
// * Neither the name of Google Inc. nor the names of its | |
// contributors may be used to endorse or promote products derived from | |
// this software without specific prior written permission. | |
// | |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
// Author: kenton@google.com (Kenton Varda) | |
// | |
// WARNING: The plugin interface is currently EXPERIMENTAL and is subject to | |
// change. | |
// | |
// protoc (aka the Protocol Compiler) can be extended via plugins. A plugin is | |
// just a program that reads a CodeGeneratorRequest from stdin and writes a | |
// CodeGeneratorResponse to stdout. | |
// | |
// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead | |
// of dealing with the raw protocol defined here. | |
// | |
// A plugin executable needs only to be placed somewhere in the path. The | |
// plugin should be named "protoc-gen-$NAME", and will then be used when the | |
// flag "--${NAME}_out" is passed to protoc. | |
package google.protobuf.compiler; | |
import "descriptor.proto"; | |
// An encoded CodeGeneratorRequest is written to the plugin's stdin. | |
message CodeGeneratorRequest { | |
// The .proto files that were explicitly listed on the command-line. The | |
// code generator should generate code only for these files. Each file's | |
// descriptor will be included in proto_file, below. | |
repeated string file_to_generate = 1; | |
// The generator parameter passed on the command-line. | |
optional string parameter = 2; | |
// FileDescriptorProtos for all files in files_to_generate and everything | |
// they import. The files will appear in topological order, so each file | |
// appears before any file that imports it. | |
// | |
// protoc guarantees that all proto_files will be written after | |
// the fields above, even though this is not technically guaranteed by the | |
// protobuf wire format. This theoretically could allow a plugin to stream | |
// in the FileDescriptorProtos and handle them one by one rather than read | |
// the entire set into memory at once. However, as of this writing, this | |
// is not similarly optimized on protoc's end -- it will store all fields in | |
// memory at once before sending them to the plugin. | |
repeated FileDescriptorProto proto_file = 15; | |
} | |
// The plugin writes an encoded CodeGeneratorResponse to stdout. | |
message CodeGeneratorResponse { | |
// Error message. If non-empty, code generation failed. The plugin process | |
// should exit with status code zero even if it reports an error in this way. | |
// | |
// This should be used to indicate errors in .proto files which prevent the | |
// code generator from generating correct code. Errors which indicate a | |
// problem in protoc itself -- such as the input CodeGeneratorRequest being | |
// unparseable -- should be reported by writing a message to stderr and | |
// exiting with a non-zero status code. | |
optional string error = 1; | |
// Represents a single generated file. | |
message File { | |
// The file name, relative to the output directory. The name must not | |
// contain "." or ".." components and must be relative, not be absolute (so, | |
// the file cannot lie outside the output directory). "/" must be used as | |
// the path separator, not "\". | |
// | |
// If the name is omitted, the content will be appended to the previous | |
// file. This allows the generator to break large files into small chunks, | |
// and allows the generated text to be streamed back to protoc so that large | |
// files need not reside completely in memory at one time. Note that as of | |
// this writing protoc does not optimize for this -- it will read the entire | |
// CodeGeneratorResponse before writing files to disk. | |
optional string name = 1; | |
// If non-empty, indicates that the named file should already exist, and the | |
// content here is to be inserted into that file at a defined insertion | |
// point. This feature allows a code generator to extend the output | |
// produced by another code generator. The original generator may provide | |
// insertion points by placing special annotations in the file that look | |
// like: | |
// @@protoc_insertion_point(NAME) | |
// The annotation can have arbitrary text before and after it on the line, | |
// which allows it to be placed in a comment. NAME should be replaced with | |
// an identifier naming the point -- this is what other generators will use | |
// as the insertion_point. Code inserted at this point will be placed | |
// immediately above the line containing the insertion point (thus multiple | |
// insertions to the same point will come out in the order they were added). | |
// The double-@ is intended to make it unlikely that the generated code | |
// could contain things that look like insertion points by accident. | |
// | |
// For example, the C++ code generator places the following line in the | |
// .pb.h files that it generates: | |
// // @@protoc_insertion_point(namespace_scope) | |
// This line appears within the scope of the file's package namespace, but | |
// outside of any particular class. Another plugin can then specify the | |
// insertion_point "namespace_scope" to generate additional classes or | |
// other declarations that should be placed in this scope. | |
// | |
// Note that if the line containing the insertion point begins with | |
// whitespace, the same whitespace will be added to every line of the | |
// inserted text. This is useful for languages like Python, where | |
// indentation matters. In these languages, the insertion point comment | |
// should be indented the same amount as any inserted code will need to be | |
// in order to work correctly in that context. | |
// | |
// The code generator that generates the initial file and the one which | |
// inserts into it must both run as part of a single invocation of protoc. | |
// Code generators are executed in the order in which they appear on the | |
// command line. | |
// | |
// If |insertion_point| is present, |name| must also be present. | |
optional string insertion_point = 2; | |
// The file contents. | |
optional string content = 15; | |
} | |
repeated File file = 15; | |
} | |
<?php | |
namespace DrSlump\Protobuf; | |
use DrSlump\Protobuf; | |
class Descriptor | |
{ | |
/** @var String Holds the class name of the message */ | |
protected $class; | |
/** @var String Holds the original proto name */ | |
protected $name; | |
/** @var \DrSlump\Protobuf\Field[] */ | |
protected $fields = array(); | |
/** @var array - Cache the relation between names and tags */ | |
protected $names = array(); | |
/** | |
* @param string $class | |
* @param string $name | |
*/ | |
public function __construct($class, $name = null) | |
{ | |
$this->class = trim($class, '\\ '); | |
$this->name = $name ? trim($name, '. ') : NULL; | |
} | |
/** | |
* @return string | |
*/ | |
public function getClass() | |
{ | |
return $this->class; | |
} | |
/** | |
* @return string|null | |
*/ | |
public function getName() | |
{ | |
return $this->name; | |
} | |
/** | |
* Obtain the list of fields in the message | |
* | |
* @return \DrSlump\Protobuf\Field[] | |
*/ | |
public function getFields() | |
{ | |
return $this->fields; | |
} | |
/** | |
* Adds a field to the message | |
* | |
* @param \DrSlump\Protobuf\Field $field | |
* @param bool $isExtension | |
*/ | |
public function addField(Protobuf\Field $field, $isExtension = false) | |
{ | |
$field->extension = $isExtension; | |
$this->fields[ $field->number ] = $field; | |
} | |
/** | |
* Obtain a field descriptor by its tag number | |
* | |
* @param int $tag | |
* @return \DrSlump\Protobuf\Field | NULL | |
*/ | |
public function getField($tag) | |
{ | |
return isset($this->fields[$tag]) | |
? $this->fields[$tag] | |
: NULL; | |
} | |
/** | |
* Obtain a field descriptor by its name | |
* | |
* @param string $name | |
* @return \DrSlump\Protobuf\Field | NULL | |
*/ | |
public function getFieldByName($name) | |
{ | |
// Check cached map | |
if (isset($this->names[$name])) { | |
return $this->getField($this->names[$name]); | |
} | |
// Loop thru all fields to find it | |
foreach ($this->fields as $tag=>$field) { | |
// Cache it for next calls | |
$fname = $field->getName(); | |
$this->names[$fname] = $tag; | |
if ($name === $fname) { | |
return $field; | |
} | |
} | |
return null; | |
} | |
/** | |
* Check if the given tag number matches a field | |
* | |
* @param int $tag | |
* @return bool | |
*/ | |
public function hasField($tag) | |
{ | |
return isset($this->fields[$tag]); | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf; | |
class Exception extends \Exception | |
{ | |
} |
<?php | |
namespace DrSlump\Protobuf; | |
use DrSlump\Protobuf; | |
class Field | |
{ | |
public $number; | |
public $name; | |
public $type = Protobuf::TYPE_UNKNOWN; | |
public $rule = Protobuf::RULE_OPTIONAL; | |
public $reference; | |
public $default; | |
public $packed = false; | |
public $extension = false; | |
public function __construct(array $opts = array()) | |
{ | |
if (!empty($opts)) { | |
if (isset($opts['number'])) $this->number = (int)$opts['number']; | |
if (isset($opts['name'])) $this->name = $opts['name']; | |
if (isset($opts['type'])) $this->type = (int)$opts['type']; | |
if (isset($opts['rule'])) $this->rule = (int)$opts['rule']; | |
if (isset($opts['packed'])) $this->packed = (bool)$opts['packed']; | |
if (isset($opts['reference'])) $this->reference = $opts['reference']; | |
if (isset($opts['default'])) $this->default = $opts['default']; | |
if (isset($opts['extension'])) $this->extension = (bool)$opts['extension']; | |
} | |
} | |
public function getNumber() | |
{ | |
return $this->number; | |
} | |
public function getType() | |
{ | |
return $this->type; | |
} | |
public function getName() | |
{ | |
return $this->name; | |
} | |
public function getReference() | |
{ | |
return $this->reference; | |
} | |
public function getDefault() | |
{ | |
return $this->default; | |
} | |
public function hasDefault() | |
{ | |
return $this->default !== NULL; | |
} | |
public function isOptional() | |
{ | |
return $this->rule === Protobuf::RULE_OPTIONAL; | |
} | |
public function isRequired() | |
{ | |
return $this->rule === Protobuf::RULE_REQUIRED; | |
} | |
public function isRepeated() | |
{ | |
return $this->rule === Protobuf::RULE_REPEATED; | |
} | |
public function isPacked() | |
{ | |
return $this->packed; | |
} | |
public function isExtension() | |
{ | |
return $this->extension; | |
} | |
} |
<?php | |
namespace DrSlump\Protobuf; | |
use DrSlump\Protobuf; | |
abstract class Message implements \ArrayAccess | |
{ | |
/** @var \Closure[] */ | |
static protected $__extensions = array(); | |
/** @var \DrSlump\Protobuf\Descriptor */ | |
protected $_descriptor; | |
/** @var array Store data for extension fields */ | |
protected $_extensions = array(); | |
/** @var array Store data for unknown values */ | |
protected $_unknown = array(); | |
/** | |
* @static | |
* @abstract | |
* @return \DrSlump\Protobuf\Descriptor | |
*/ | |
public static function descriptor() | |
{ | |
throw new \BadMethodCallException('This method should be implemented in inherited classes'); | |
} | |
/** | |
* Register an extension configuration callback | |
* | |
* @static | |
* @param \Closure $fn | |
*/ | |
public static function extension(\Closure $fn) | |
{ | |
static::$__extensions[] = $fn; | |
} | |
/** | |
* @param string $data | |
*/ | |
public function __construct($data = null) | |
{ | |
// Cache the descriptor instance | |
$this->_descriptor = Protobuf::getRegistry()->getDescriptor($this); | |
// Assign default values to extensions | |
foreach ($this->_descriptor->getFields() as $f) { | |
if ($f->isExtension() && $f->hasDefault()) { | |
$this->_extensions[$f->getName()] = $f->getDefault(); | |
} | |
} | |
if (NULL !== $data) { | |
$this->parse($data); | |
} | |
} | |
// Implements ArrayAccess for extensions and unknown fields | |
public function offsetExists($offset) | |
{ | |
if (is_numeric($offset)) { | |
return $this->_has($offset); | |
} else { | |
return $this->hasExtension($offset); | |
} | |
} | |
public function offsetSet($offset, $value) | |
{ | |
if (is_numeric($offset)) { | |
$this->_set($offset, $value); | |
} else { | |
$this->setExtension($offset, $value); | |
} | |
} | |
public function offsetGet( $offset ) | |
{ | |
if (is_numeric($offset)) { | |
return $this->_get($offset); | |
} else { | |
return $this->getExtension($offset); | |
} | |
} | |
public function offsetUnset( $offset ) | |
{ | |
if (is_numeric($offset)) { | |
$this->_clear($offset); | |
} else { | |
$this->clearExtension($offset); | |
} | |
} | |
/** | |
* Parse the given data to hydrate the object | |
* | |
* @param string $data | |
* @param CodecInterface|null $codec | |
*/ | |
public function parse($data, Protobuf\CodecInterface $codec = null) | |
{ | |
$codec = Protobuf::getCodec($codec); | |
$codec->decode($this, $data); | |
} | |
/** | |
* Serialize the current object data | |
* | |
* @param CodecInterface|null $codec | |
* @return string | |
*/ | |
public function serialize(Protobuf\CodecInterface $codec = null) | |
{ | |
$codec = Protobuf::getCodec($codec); | |
return $codec->encode($this); | |
} | |
/** | |
* Checks if the given tag number is set | |
* | |
* @param int $tag | |
* @return bool | |
*/ | |
public function _has($tag) | |
{ | |
if ($this->_descriptor->hasField($tag)) { | |
$f = $this->_descriptor->getField($tag); | |
$name = $f->getName(); | |
if ($f->isExtension()) { | |
return $f->isRepeated() | |
? count($this->_extensions[$name]) > 0 | |
: $this->_extensions[$name] !== NULL; | |
} else { | |
return $f->isRepeated() | |
? count($this->$name) > 0 | |
: $this->$name !== NULL; | |
} | |
} | |
return false; | |
} | |
/** | |
* Get the value by tag number | |
* | |
* @param int $tag | |
* @param int|null $idx | |
* @return mixed | |
*/ | |
public function _get($tag, $idx = null) | |
{ | |
$f = $this->_descriptor->getField($tag); | |
if (!$f) { | |
return null; | |
} | |
$name = $f->getName(); | |
if (!$f->isExtension()) { | |
return $idx !== NULL | |
? $this->{$name}[$idx] | |
: $this->$name; | |
} else { | |
return $idx !== NULL | |
? $this->_extensions[$name][$idx] | |
: $this->_extensions[$name]; | |
} | |
} | |
/** | |
* Sets the value by tag number | |
* | |
* @throws \Exception If trying to set an unknown field | |
* @param int $tag | |
* @param mixed $value | |
* @param int|null $idx | |
* @return \DrSlump\Protobuf\Message - Fluent interface | |
*/ | |
public function _set($tag, $value, $idx = null) | |
{ | |
$f = $this->_descriptor->getField($tag); | |
if (!$f) { | |
throw new \Exception('Unknown fields not supported'); | |
} | |
$name = $f->getName(); | |
if (!$f->isExtension()) { | |
if ($idx === NULL) { | |
$this->$name = $value; | |
} else { | |
$this->{$name}[$idx] = $value; | |
} | |
} else { | |
if ($idx === NULL) { | |
$this->_extensions[$name] = $value; | |
} else { | |
$this->_extensions[$name][$idx] = $value; | |
} | |
} | |
return $this; | |
} | |
/** | |
* Adds a new value to a repeated field by tag number | |
* | |
* @throws \Exception If trying to modify an unknown field | |
* @param int $tag | |
* @param mixed $value | |
* @return Message | |
*/ | |
public function _add($tag, $value) | |
{ | |
$f = $this->_descriptor->getField($tag); | |
if (!$f) { | |
throw new \Exception('Unknown fields not supported'); | |
} | |
$name = $f->getName(); | |
if (!$f->isExtension()) { | |
$this->{$name}[] = $value; | |
} else { | |
$this->_extensions[$name][] = $value; | |
} | |
return $this; | |
} | |
/** | |
* Clears/Resets a field by tag number | |
* | |
* @throws \Exception If trying to modify an unknown field | |
* @param int $tag | |
* @return \DrSlump\Protobuf\Message - Fluent interface | |
*/ | |
public function _clear($tag) | |
{ | |
$f = $this->_descriptor->getField($tag); | |
if (!$f) { | |
throw new \Exception('Unknown fields not supported'); | |
} | |
$name = $f->getName(); | |
if (!$f->isExtension()) { | |
$this->$name = $f->isRepeated() | |
? array() | |
: NULL; | |
} else { | |
$this->_extensions[$name] = $f->isRepeated() | |
? array() | |
: NULL; | |
} | |
return $this; | |
} | |
// Extensions public methods. | |
// @todo Check if extension name is defined | |
/** | |
* Checks if an extension field is set | |
* | |
* @param string $extname | |
* @return bool | |
*/ | |
public function hasExtension($extname) | |
{ | |
return isset($this->_extensions[$extname]); | |
} | |
/** | |
* Get the value of an extension field | |
* | |
* @param string $extname | |
* @param int|null $idx | |
* @return mixed | |
*/ | |
public function getExtension($extname, $idx = null) | |
{ | |
if (!isset($this->_extensions[$extname])) return NULL; | |
return $idx === NULL | |
? $this->_extensions[$extname] | |
: $this->_extensions[$extname][$idx]; | |
} | |
/** | |
* Get all the values of a repeated extension field | |
* | |
* @param string $extname | |
* @return array | |
*/ | |
public function getExtensionList($extname) | |
{ | |
return isset($this->_extensions[$extname]) | |
? $this->_extensions[$extname] | |
: array(); | |
} | |
/** | |
* Set the value for an extension field | |
* | |
* @param string $extname | |
* @param mixed $value | |
* @param int|null $idx | |
* @return \DrSlump\Protobuf\Message - Fluent Interface | |
*/ | |
public function setExtension($extname, $value, $idx = null) | |
{ | |
if (NULL !== $idx) { | |
if (empty($this->_extensions)) { | |
$this->_extensions[$extname] = array(); | |
} | |
$this->_extensions[$extname][$idx] = $value; | |
} | |
$this->_extensions[$extname] = $value; | |
return $this; | |
} | |
/** | |
* Adds a value to repeated extension field | |
* | |
* @param string $extname | |
* @param mixed $value | |
* @return \DrSlump\Protobuf\Message - Fluent Interface | |
*/ | |
public function addExtension($extname, $value) | |
{ | |
$this->_extensions[$extname][] = $value; | |
} | |
/** | |
* @param $extname | |
* @return void | |
*/ | |
public function clearExtension($extname) | |
{ | |
unset($this->_extensions[$extname]); | |
} | |
public function addUnknown(Unknown $unknown) | |
{ | |
$this->_unknown[] = $unknown; | |
} | |
public function getUnknown() | |
{ | |
return $this->_unknown; | |
} | |
public function clearUnknown() | |
{ | |
$this->_unknown = array(); | |
} | |
} | |
<?php | |
namespace DrSlump\Protobuf; | |
use DrSlump\Protobuf; | |
/** | |
* Keeps instances of the different message descriptors used. | |
* | |
*/ | |
class Registry | |
{ | |
/** @var array */ | |
protected $descriptors = array(); | |
/** | |
* @param string|\DrSlump\Protobuf\Message $message | |
* @param \DrSlump\Protobuf\Descriptor $descriptor | |
*/ | |
public function setDescriptor($message, Descriptor $descriptor) | |
{ | |
$message = is_object($message) ? get_class($message) : $message; | |
$message = ltrim($message, '\\'); | |
$this->descriptors[$message] = $descriptor; | |
} | |
/** | |
* Obtains the descriptor for the given message class, obtaining | |
* it if not yet loaded. | |
* | |
* @param string|\DrSlump\Protobuf\Message $message | |
* @return \DrSlump\Protobuf\Descriptor | |
*/ | |
public function getDescriptor($message) | |
{ | |
$message = is_object($message) ? get_class($message) : $message; | |
$message = ltrim($message, '\\'); | |
// Build a descriptor for the message | |
if (!isset($this->descriptors[$message])) { | |
$class = '\\' . $message; | |
if (!class_exists($class)) { | |
throw Protobuf\Exception('Message class "' . $class . '" not available'); | |
} | |
$this->descriptors[$message] = $class::descriptor(); | |
} | |
return $this->descriptors[$message]; | |
} | |
/** | |
* @param string|\DrSlump\Protobuf\Message $message | |
* @return bool | |
*/ | |
public function hasDescriptor($message) | |
{ | |
$message = is_object($message) ? get_class($message) : $message; | |
$message = ltrim($message, '\\'); | |
return isset($this->descriptors[$message]); | |
} | |
/** | |
* @param string|\DrSlump\Protobuf\Message $message | |
*/ | |
public function unsetDescriptor($message) | |
{ | |
$message = is_object($message) ? get_class($message) : $message; | |
$message = ltrim($message, '\\'); | |
unset($this->descriptors[$message]); | |
} | |
} |
<?php | |
namespace DrSlump\Protobuf; | |
abstract class Unknown | |
{ | |
public $tag = 0; | |
public $data = null; | |
} | |
protobuf-php(3) -- The framework | |
================================ | |
## SYNOPSIS | |
<?php | |
require_once 'DrSlump\Protobuf.php'; | |
use DrSlump\Protobuf; | |
$data = file_get_contents('data.pb'); | |
$person = new Tutorial\Person($data); | |
echo $person->getName(); | |
## DESCRIPTION | |
Protobuf-PHP is a library to generate, parse and serialize data structures | |
compatible with Google's Protocol Buffers using the PHP language. | |
## CODECS | |
The library is designed to work with a pluggable mechanism for encoding and decoding | |
messages, allowing it to be used not only to communicate using the standard binary | |
format but also with Json or XML based formats. | |
You can create your own codecs by either extending a provided one or implementing the | |
`Protobuf\CodecInterface`. Creating custom codecs offers the possibility to use | |
Protobuf-PHP code generation tool to work with legacy formats or even as a simple | |
way to interact with database adapters. | |
### Standard Binary | |
This is the standard binary format supported by the official libraries distributed | |
by Google. It's pretty much compatible with the official implementations although | |
there are some known issues, mostly regarding big integer numbers, which are documented | |
in the readme file that comes with the library. | |
### Standard TextFormat | |
The official libraries also support a text based format for debugging purposes. The | |
current implementation of this codec only supports encoding or serialization. | |
### PhpArray | |
This is more of an internal codec to ease the implementation of some others. It is | |
able to serializa message objects to PHP's associative arrays and intantiate message | |
objects from them. | |
Since most serialization libraries in PHP will natively support associative arrays, this | |
codec can be used as an easy way to incorporate those formats for their use | |
with Protobuf messages. The Json and XML codecs are examples of this use case. | |
### JSON | |
It allows to generate or consume JSON formatted strings, which is a very popular | |
format for REST based web services for example. This codec can be used to communicate | |
with JavaScript in the browser or with third party REST web services. | |
### ProtoJson | |
[ProtoJson](https://github.com/drslump/ProtoJson) allows to apply some payload | |
minification strategies when working with JSON formatted messages. Taking advantatge | |
of Protobuf's property names mapping to a integer number, it offers two encoding | |
variants (_TagMap_ and _Indexed_) that use that number instead of the field name | |
as key in the messages to reduce the total size of the payload. | |
### XML | |
A very simple codec to work with XML based messages. It has no knowledge of namespaces | |
and other advanced XML features but should be enough to integrate with third parties | |
that are restricted to simple XML payloads. It can also serve as a base for more | |
customized integrations, by extendind this codec to consume and generate XML messages | |
specific to your service. | |
## ANNOTATED MESSAGES | |
While the most common use case is to use the protoc-gen-php(1) `protoc` plugin to | |
generate source code representing the messages defined in .proto files, it's also | |
possible to define messages at runtime without the code generation step. | |
An easy way to define messages directly in your code is to use the `Protobuf\AnnotatedMessage` | |
abstract class, which allows to annotate your classes so that the _codecs_ know how | |
to parse and serialize those messages. | |
class Person extends \DrSlump\Protobuf\AnnotatedMessage { | |
/** @protobuf(tag=1, type=string, required) */ | |
public $name; | |
/** @protobuf(tag=2, type=int32, required) */ | |
public $id; | |
/** @protobuf(tag=3, type=string, optional) */ | |
public $email; | |
/** @protobuf(tag=4, repeated, type=message, reference=Person) */ | |
public $friends = array(); | |
} | |
## EXAMPLES | |
## BUGS | |
Please report bugs using GitHub's issue tracker at http://github.com/drslump/protobuf-php/issues | |
## COPYRIGHT | |
Protobuf for PHP is Copyright (C) 2011 Ivan -DrSlump- Montes <http://pollinimini.net> | |
## SEE ALSO | |
protoc-gen-php(1), protobuf-php(5), | |
<http://github.com/drslump/protobuf-php> | |
protobuf-php(5) -- Proto files | |
================================ | |
## SYNOPSIS | |
Protobuf for PHP supports a few custom options for proto files. | |
## DESCRIPTION | |
Proto files processed with Protobuf for PHP can use a number of custom options | |
that affect the generated source code. | |
* `php.suffix` <string>: | |
Sets a custom suffix for the generated PHP files. By default ".php" is used. | |
* `php.namespace` <string>: | |
Defines the namespace to use for the generated PHP classes. | |
* `php.package` <string>: | |
An alias for `php.namespace` | |
* `php.multifile` <boolean>: | |
By default a single PHP file is generated for each Proto file processed, | |
including in it all the messages, enums and extensions defined in the proto | |
definition. If this option is set to `true` then each message and enum is | |
generated in a separate file, following PEAR's conventions, and if extensions | |
are pressent in the proto definition a file named after the proto file with the | |
suffix "-extensions" will contain them. | |
* `php.generic_services` <boolean>: | |
By default no service interfaces will be generated. If this option is set | |
to true then Interfaces will be created for each `service` definition found, | |
including a method named after each `rpc` entry. | |
## EXAMPLES ## | |
option (php.suffix) = ".pb.php" | |
option (php.namespace) = "MyOrg.Protos" | |
option (php.multifile) = true | |
option (php.generic_services) = true | |
## BUGS ## | |
Please report bugs using GitHub's issue tracker at http://github.com/drslump/protobuf-php/issues | |
## COPYRIGHT ## | |
Protobuf for PHP is Copyright (C) 2011 Ivan -DrSlump- Montes <http://pollinimini.net> | |
## SEE ALSO | |
protoc-gen-php(1), protobuf-php(3), | |
<http://github.com/drslump/protobuf-php> | |
protoc-gen-php(1) -- protoc compiler plugin | |
=========================================== | |
## SYNOPSIS | |
`protoc-gen-php` [`-v`] [`-o` _directory_] [`-i` _directory_] <file>... | |
## DESCRIPTION | |
**protoc-gen-php** is a Google's Protocol Buffers compiler plugin | |
for the `protoc` tool. It generates PHP classes compatible with | |
**Protobuf for PHP** from .proto files. | |
## REQUIREMENTS ## | |
**protoc-gen-php** is written in PHP using features first found on | |
PHP 5.3. It also requires the Console_CommandLine package from Pear. | |
Additionally you'll also need to have a working copy of Google Protocol | |
Buffers's _protoc_ command, version 2.3 or above, available on your path. | |
## OPTIONS ## | |
The command accepts the following command-line options (switches). | |
* `-v`, `--verbose`: | |
Enables verbose mode. Additional information will be printed when | |
processing the files. | |
* `-h`, `--help`: | |
Prints the usage help message and quits. | |
* `-i` _directory_, `--include`=_directory_: | |
Tells the protoc compiler to look into that directory when resolving | |
import statements. Note that you can use this switch more than once | |
to configure multiple directories. | |
* `-o` _directory_, `--out`=_directory_: | |
Tells the protoc compiler to create generated files in the given | |
directory. If not set it will create the files in the working | |
directory. | |
* `--protoc`=_path to protoc binary_: | |
If you don't happen to have the `protoc` binary in your path, you can | |
use this option to indicate a path to it. | |
* `--skip-imported` | |
Flags the compiler to only generate source code for the proto file | |
explicitely given on the command line. This means that imported files | |
will not be generated when using this option. | |
* `--comments` | |
Parses the .proto files looking for multiline comments (/* ... */) to | |
include them in the generated files. | |
* `-Ddefine`, `-Ddefine`=_value_: | |
Defines an option (defaults to true if no value given) to pass to | |
the generator. See protobuf-php(5) for supported options, noting that | |
the `php.` prefix shall not be used here. | |
## EXAMPLES ## | |
Generate a PHP file from a proto file: | |
$ protoc-gen-php tutorial.proto | |
Generate PHP files in the "build" directory for each proto file found the | |
"protos" directory: | |
$ protoc-gen-php -o build protos/*.proto | |
Generate a PHP file from a proto file using imports from an include path: | |
$ protoc-gen-php -i ./protos protos/tutorial.proto | |
Generate a PHP file with a custom extension | |
$ protoc-gen-php -Dsuffix=pb.php tutorial.proto | |
## BUGS ## | |
Please report bugs using GitHub's issue tracker at http://github.com/drslump/protobuf-php/issues | |
## COPYRIGHT ## | |
Protobuf for PHP is Copyright (C) 2011 Ivan -DrSlump- Montes <http://pollinimini.net> | |
## SEE ALSO | |
protobuf-php(3), protobuf-php(5), | |
<http://github.com/drslump/protobuf-php> | |
<?xml version="1.0" encoding="UTF-8"?> | |
<package packagerversion="1.8.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 | |
http://pear.php.net/dtd/tasks-1.0.xsd | |
http://pear.php.net/dtd/package-2.0 | |
http://pear.php.net/dtd/package-2.0.xsd"> | |
<name>Protobuf</name> | |
<channel>pear.pollinimini.net</channel> | |
<summary>PHP implementation of Google's Protocol Buffers</summary> | |
<description> | |
Protobuf for PHP is an implementation of Google's Protocol Buffers for the | |
PHP language, supporting its binary data serialization and including a | |
protoc plugin to generate PHP classes from .proto files. | |
</description> | |
<lead> | |
<name>Iván -DrSlump- Montes</name> | |
<user>drslump</user> | |
<email>drslump@pollinimini.net</email> | |
<active>yes</active> | |
</lead> | |
<date>{DATE}</date> | |
<time>{TIME}</time> | |
<version> | |
<release>{VERSION}</release> | |
<api>{VERSION}</api> | |
</version> | |
<stability> | |
<release>beta</release> | |
<api>beta</api> | |
</stability> | |
<license uri="http://creativecommons.org/licenses/MIT">The MIT License</license> | |
<notes>http://github.com/drslump/Protobuf-PHP</notes> | |
<contents> | |
<dir name="/"> | |
<file baseinstalldir="/" name="LICENSE" role="doc"/> | |
<file baseinstalldir="/" name="README.md" role="doc"/> | |
<file baseinstalldir="/" name="protoc-gen-php.php" role="script"> | |
<tasks:replace from="/usr/bin/env php" to="php_bin" type="pear-config"/> | |
<tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> | |
<tasks:replace from="@package_version@" to="version" type="package-info" /> | |
</file> | |
<file baseinstalldir="/" name="protoc-gen-php.bat" role="script"> | |
<tasks:replace from="@php_bin@" to="php_bin" type="pear-config" /> | |
<tasks:replace from="@bin_dir@" to="bin_dir" type="pear-config" /> | |
<tasks:replace from="@package_version@" to="version" type="package-info" /> | |
</file> | |
{DIRS} | |
</dir> | |
</contents> | |
<dependencies> | |
<required> | |
<php> | |
<min>5.3.0</min> | |
</php> | |
<pearinstaller> | |
<min>1.9.2</min> | |
</pearinstaller> | |
<package> | |
<name>Console_CommandLine</name> | |
<channel>pear.php.net</channel> | |
<min>1.1.0</min> | |
</package> | |
</required> | |
</dependencies> | |
<phprelease> | |
<installconditions> | |
<os> | |
<name>windows</name> | |
</os> | |
</installconditions> | |
<filelist> | |
<install as="protoc-gen-php" name="protoc-gen-php.php" /> | |
<install as="protoc-gen-php.bat" name="protoc-gen-php.bat" /> | |
</filelist> | |
</phprelease> | |
<phprelease> | |
<filelist> | |
<install as="protoc-gen-php" name="protoc-gen-php.php" /> | |
<ignore name="protoc-gen-php.bat" /> | |
</filelist> | |
</phprelease> | |
</package> | |
@echo off | |
REM Protobuf-PHP | |
REM Copyright (C) 2011 Iván -DrSlump- Montes <drslump@pollinimini.net> | |
REM | |
REM This source file is subject to the MIT license that is bundled | |
REM with this package in the file LICENSE. | |
REM It is also available through the world-wide-web at this URL: | |
REM http://creativecommons.org/licenses/MIT/ | |
if "%PHPBIN%" == "" set PHPBIN=@php_bin@ | |
if not exist "%PHPBIN%" if "%PHP_PEAR_PHP_BIN%" neq "" goto USE_PEAR_PATH | |
GOTO RUN | |
:USE_PEAR_PATH | |
set PHPBIN=%PHP_PEAR_PHP_BIN% | |
:RUN | |
"%PHPBIN%" "@bin_dir@\protoc-gen-php" %* | |
#!/usr/bin/env php | |
<?php | |
// The MIT License | |
// | |
// Copyright (c) 2011 Iván -DrSlump- Montes | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE. | |
// Set up default timezone | |
date_default_timezone_set('GMT'); | |
// For non pear packaged versions use relative include path | |
if (strpos('@php_bin@', '@php_bin') === 0) { | |
set_include_path(__DIR__ . DIRECTORY_SEPARATOR . 'library' . PATH_SEPARATOR . get_include_path()); | |
} | |
require_once 'DrSlump/Protobuf.php'; | |
// Setup autoloader | |
\DrSlump\Protobuf::autoload(); | |
try { | |
// Run the cli interface | |
\DrSlump\Protobuf\Compiler\Cli::run(__FILE__); | |
exit(0); | |
} catch(Exception $e) { | |
fputs(STDERR, (string)$e . PHP_EOL); | |
exit(1); | |
} | |
Binary files /dev/null and b/lib/Protobuf-PHP/protoc.exe differ
<?php | |
include_once("library/DrSlump/Protobuf.php"); | |
include_once("library/DrSlump/Protobuf/Message.php"); | |
include_once("library/DrSlump/Protobuf/Registry.php"); | |
include_once("library/DrSlump/Protobuf/Descriptor.php"); | |
include_once("library/DrSlump/Protobuf/Field.php"); | |
include_once("gtfs-realtime.php"); | |
include_once("library/DrSlump/Protobuf/CodecInterface.php"); | |
include_once("library/DrSlump/Protobuf/Codec/PhpArray.php"); | |
include_once("library/DrSlump/Protobuf/Codec/Binary.php"); | |
include_once("library/DrSlump/Protobuf/Codec/Binary/Writer.php"); | |
include_once("library/DrSlump/Protobuf/Codec/Json.php"); | |
//print_r(get_declared_classes()); | |
$fm = new transit_realtime\FeedMessage(); | |
$fh = new transit_realtime\FeedHeader(); | |
$fh->setGtfsRealtimeVersion(1); | |
$fh->setTimestamp(time()); | |
$fm->setHeader($fh); | |
$fe = new transit_realtime\FeedEntity(); | |
$fe->setId("1234"); | |
$fe->setIsDeleted(false); | |
$alert = new transit_realtime\Alert(); | |
$tr = new transit_realtime\TimeRange(); | |
$tr->setStart(000); | |
$tr->setEnd(001); | |
$alert-> addActivePeriod($tr); | |
$es = new transit_realtime\EntitySelector(); | |
$es->setAgencyId("0"); | |
$es->setStopId("0"); | |
$es->setRouteId("0"); | |
$td = new transit_realtime\TripDescriptor(); | |
$td->setTripId("0"); | |
$es->setTrip($td); | |
$alert-> addInformedEntity($es); | |
$alert->setCause(constant("transit_realtime\Alert\Cause::"."UNKNOWN_CAUSE")); | |
$alert->setEffect(constant("transit_realtime\Alert\Effect::"."UNKNOWN_EFFECT")); | |
$tsUrl = new transit_realtime\TranslatedString(); | |
$tUrl = new transit_realtime\TranslatedString\Translation(); | |
$tUrl->setText("http"); | |
$tUrl->setLanguage("en"); | |
$tsUrl->addTranslation($tUrl); | |
$alert->setUrl($tsUrl); | |
$tsHeaderText= new transit_realtime\TranslatedString(); | |
$tHeaderText = new transit_realtime\TranslatedString\Translation(); | |
$tHeaderText->setText("http"); | |
$tHeaderText->setLanguage("en"); | |
$tsHeaderText->addTranslation($tHeaderText); | |
$alert->setHeaderText($tsHeaderText); | |
$tsDescriptionText= new transit_realtime\TranslatedString(); | |
$tDescriptionText = new transit_realtime\TranslatedString\Translation(); | |
$tDescriptionText->setText("http"); | |
$tDescriptionText->setLanguage("en"); | |
$tsDescriptionText->addTranslation($tDescriptionText); | |
$alert->setDescriptionText($tsDescriptionText); | |
$fe->setAlert($alert); | |
$fm->addEntity($fe); | |
//var_dump($fm); | |
//$codec = new DrSlump\Protobuf\Codec\Binary(); | |
//echo $codec->encode($fm); | |
//$codec = new DrSlump\Protobuf\Codec\Json(); | |
//echo $codec->encode($fm); | |
$codec = new DrSlump\Protobuf\Codec\PhpArray(); | |
print_r($codec->encode($fm)); | |
?> |
<?php | |
include_once("library/DrSlump/Protobuf.php"); | |
include_once("library/DrSlump/Protobuf/Message.php"); | |
include_once("library/DrSlump/Protobuf/Registry.php"); | |
include_once("library/DrSlump/Protobuf/Descriptor.php"); | |
include_once("library/DrSlump/Protobuf/Field.php"); | |
include_once("gtfs-realtime.php"); | |
include_once("library/DrSlump/Protobuf/CodecInterface.php"); | |
include_once("library/DrSlump/Protobuf/Codec/PhpArray.php"); | |
include_once("library/DrSlump/Protobuf/Codec/Binary.php"); | |
include_once("library/DrSlump/Protobuf/Codec/Binary/Writer.php"); | |
include_once("library/DrSlump/Protobuf/Codec/Json.php"); | |
//print_r(get_declared_classes()); | |
$fm = new transit_realtime\FeedMessage(); | |
$fh = new transit_realtime\FeedHeader(); | |
$fh->setGtfsRealtimeVersion(1); | |
$fh->setTimestamp(time()); | |
$fm->setHeader($fh); | |
$fe = new transit_realtime\FeedEntity(); | |
$fe->setId("1234"); | |
$fe->setIsDeleted(false); | |
$tu = new transit_realtime\TripUpdate(); | |
$td = new transit_realtime\TripDescriptor(); | |
$td->setRouteId("0"); | |
$tu->setTrip($td); | |
$stu = new transit_realtime\TripUpdate\StopTimeUpdate(); | |
$stu->setStopId("1"); | |
$stu->setScheduleRelationship(transit_realtime\TripUpdate\StopTimeUpdate\ScheduleRelationship::SKIPPED); | |
$tu->addStopTimeUpdate($stu); | |
$fe->setTripUpdate($tu); | |
$fm->addEntity($fe); | |
//var_dump($fm); | |
//$codec = new DrSlump\Protobuf\Codec\Binary(); | |
//echo $codec->encode($fm); | |
//$codec = new DrSlump\Protobuf\Codec\Json(); | |
//echo $codec->encode($fm); | |
$codec = new DrSlump\Protobuf\Codec\PhpArray(); | |
print_r($codec->encode($fm)); | |
?> |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
error_reporting(E_ALL); | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/repeated.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
describe "Binary Codec" | |
before | |
$codec = new Protobuf\Codec\Binary(); | |
Protobuf::setDefaultCodec($codec); | |
$W->bin_simple = file_get_contents(__DIR__ . '/protos/simple.bin'); | |
$W->bin_book = file_get_contents(__DIR__ . '/protos/addressbook.bin'); | |
$W->bin_repeated_string = file_get_contents(__DIR__ . '/protos/repeated-string.bin'); | |
$W->bin_repeated_int32 = file_get_contents(__DIR__ . '/protos/repeated-int32.bin'); | |
$W->bin_repeated_nested = file_get_contents(__DIR__ . '/protos/repeated-nested.bin'); | |
end; | |
describe "serialize" | |
it "a simple message comparing types with protoc" | |
$max = pow(2, 54)-1; | |
$min = -$max; | |
$fields = array( | |
'double' => array(1, 0.1, 1.0, -1, -0.1, -100000, 123456789.12345, -123456789.12345), | |
'float' => array(1, 0.1, 1.0, -1, -0.1, -100000, 12345.123, -12345.123), | |
'int64' => array(0, 1, -1, 123456789123456789, -123456789123456789, $min), | |
'uint64' => array(0, 1, 1000, 123456789123456789, PHP_INT_MAX, $max), | |
'int32' => array(0, 1, -1, 123456789, -123456789), | |
'fixed64' => array(0, 1, 1000, 123456789123456789), | |
'fixed32' => array(0, 1, 1000, 123456789), | |
'bool' => array(0, 1), | |
'string' => array("", "foo"), | |
'bytes' => array("", "foo"), | |
'uint32' => array(0, 1, 1000, 123456789), | |
'sfixed32' => array(0, 1, -1, 123456789, -123456789), | |
'sfixed64' => array(0, 1, -1, 123456789123456789, -123456789123456789), | |
'sint32' => array(0, 1, -1, 123456789, -123456789), | |
'sint64' => array(0, 1, -1, 123456789123456789, -123456789123456789, $min, $max), | |
); | |
foreach ($fields as $field=>$values) { | |
foreach ($values as $value) { | |
$simple = new Tests\Simple(); | |
$simple->$field = $value; | |
$bin = Protobuf::encode($simple); | |
if (is_string($value)) $value = '"' . $value . '"'; | |
exec("echo '$field: $value' | protoc --encode=tests.Simple -Itests tests/protos/simple.proto", $out); | |
$out = implode("\n", $out); | |
$printValue = var_export($value, true); | |
bin2hex($bin) should eq (bin2hex($out)) as "Encoding $field with value $printValue"; | |
} | |
} | |
foreach ($fields as $field=>$values) { | |
foreach ($values as $value) { | |
$cmdValue = is_string($value) | |
? '"' . $value . '"' | |
: $value; | |
exec("echo '$field: $cmdValue' | protoc --encode=tests.Simple -Itests tests/protos/simple.proto", $out); | |
$out = implode("\n", $out); | |
$simple = Protobuf::decode('\tests\Simple', $out); | |
// Hack the comparison for float precision | |
if (is_float($simple->$field)) { | |
$precision = strlen($value) - strpos($value, '.'); | |
$simple->$field = round($simple->$field, $precision); | |
} | |
$printValue = var_export($value, true); | |
$simple->$field should eq $value as "Decoding $field with value $printValue"; | |
} | |
} | |
end. | |
it. "a message with repeated fields" | |
$repeated = new Tests\Repeated(); | |
$repeated->addString('one'); | |
$repeated->addString('two'); | |
$repeated->addString('three'); | |
$bin = Protobuf::encode($repeated); | |
$bin should be $W->bin_repeated_string; | |
$repeated = new Tests\Repeated(); | |
$repeated->addInt(1); | |
$repeated->addInt(2); | |
$repeated->addInt(3); | |
$bin = Protobuf::encode($repeated); | |
$bin should be $W->bin_repeated_int32; | |
$repeated = new Tests\Repeated(); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(1); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(2); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(3); | |
$repeated->addNested($nested); | |
$bin = Protobuf::encode($repeated); | |
$bin should eq $W->bin_repeated_nested; | |
end. | |
it. "a complex message" | |
$book = new Tests\AddressBook(); | |
$person = new Tests\Person(); | |
$person->name = 'John Doe'; | |
$person->id = 2051; | |
$person->email = 'john.doe@gmail.com'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '1231231212'; | |
$phone->type = Tests\Person\PhoneType::HOME; | |
$person->addPhone($phone); | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '55512321312'; | |
$phone->type = Tests\Person\PhoneType::MOBILE; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$person = new Tests\Person(); | |
$person->name = 'Iván Montes'; | |
$person->id = 23; | |
$person->email = 'drslump@pollinimini.net'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '3493123123'; | |
$phone->type = Tests\Person\PhoneType::WORK; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$bin = Protobuf::encode($book); | |
$bin should eq $W->bin_book but not be false; | |
end. | |
end; | |
describe "unserialize" | |
it "a simple message" | |
$simple = Protobuf::decode('Tests\Simple', $W->bin_simple); | |
$simple should be instanceof 'Tests\Simple'; | |
$simple->string should be 'foo'; | |
$simple->int32 should be -123456789; | |
end. | |
it "a message with repeated fields" | |
$repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_string); | |
$repeated should be instanceof 'Tests\Repeated'; | |
$repeated->getString() should eq array('one', 'two', 'three'); | |
$repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_int32); | |
$repeated should be instanceof 'Tests\Repeated'; | |
$repeated->getInt() should eq array(1,2,3); | |
$repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_nested); | |
$repeated should be instanceof 'Tests\Repeated'; | |
foreach ($repeated->getNested() as $i=>$nested) { | |
$nested->getId() should eq ($i+1); | |
} | |
end. | |
it "a complex message" | |
$complex = Protobuf::decode('Tests\AddressBook', $W->bin_book); | |
count($complex->person) should eq 2; | |
$complex->getPerson(0)->name should eq 'John Doe'; | |
$complex->getPerson(1)->name should eq 'Iván Montes'; | |
$complex->getPerson(0)->getPhone(1)->number should eq '55512321312'; | |
end. | |
end; | |
describe "multi codec" | |
before | |
$W->jsonCodec = new Protobuf\Codec\Json(); | |
end | |
it "a simple message" | |
$simple = Protobuf::decode('Tests\Simple', $W->bin_simple); | |
$json = $W->jsonCodec->encode($simple); | |
$simple = $W->jsonCodec->decode(new \Tests\Simple, $json); | |
$bin = Protobuf::encode($simple); | |
$bin should be $W->bin_simple; | |
end. | |
it "a message with repeated fields" | |
$repeated = Protobuf::decode('Tests\Repeated', $W->bin_repeated_nested); | |
$json = $W->jsonCodec->encode($repeated); | |
$repeated = $W->jsonCodec->decode(new \Tests\Repeated, $json); | |
$bin = Protobuf::encode($repeated); | |
$bin should be $W->bin_repeated_nested; | |
end. | |
end; | |
end; | |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/repeated.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
include_once __DIR__ . '/protos/Annotated/Simple.php'; | |
include_once __DIR__ . '/protos/Annotated/Repeated.php'; | |
include_once __DIR__ . '/protos/Annotated/Addressbook.php'; | |
describe "JSON Codec" | |
before | |
Protobuf::setDefaultCodec(new ProtoBuf\Codec\Json); | |
end | |
describe "serialize" | |
it "a simple message" | |
$simple = new Tests\Simple(); | |
$simple->string = 'FOO'; | |
$simple->int32 = 1000; | |
$json = Protobuf::encode($simple); | |
$json. should. eq. '{"int32":1000,"string":"FOO"}'; | |
end. | |
it. "a message with repeated fields" | |
$repeated = new \Tests\Repeated(); | |
$repeated->addString('one'); | |
$repeated->addString('two'); | |
$repeated->addString('three'); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '{"string":["one","two","three"]}'; | |
$repeated = new Tests\Repeated(); | |
$repeated->addInt(1); | |
$repeated->addInt(2); | |
$repeated->addInt(3); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '{"int":[1,2,3]}'; | |
$repeated = new Tests\Repeated(); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(1); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(2); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(3); | |
$repeated->addNested($nested); | |
$json = Protobuf::encode($repeated); | |
$json should eq '{"nested":[{"id":1},{"id":2},{"id":3}]}'; | |
end. | |
it. "a complex message" | |
$book = new Tests\AddressBook(); | |
$person = new Tests\Person(); | |
$person->name = 'John Doe'; | |
$person->id = 2051; | |
$person->email = 'john.doe@gmail.com'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '1231231212'; | |
$phone->type = Tests\Person\PhoneType::HOME; | |
$person->addPhone($phone); | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '55512321312'; | |
$phone->type = Tests\Person\PhoneType::MOBILE; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$person = new Tests\Person(); | |
$person->name = 'Iván Montes'; | |
$person->id = 23; | |
$person->email = 'drslump@pollinimini.net'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '3493123123'; | |
$phone->type = Tests\Person\PhoneType::WORK; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$json = Protobuf::encode($book); | |
$expected = '{ | |
"person":[ | |
{ | |
"name":"John Doe", | |
"id":2051, | |
"email":"john.doe@gmail.com", | |
"phone":[ | |
{"number":"1231231212","type":1}, | |
{"number":"55512321312","type":0} | |
] | |
}, | |
{ | |
"name":"Iv\u00e1n Montes", | |
"id":23, | |
"email":"drslump@pollinimini.net", | |
"phone":[{"number":"3493123123","type":2}] | |
} | |
] | |
}'; | |
$expected = preg_replace('/\n\s*/', '', $expected); | |
$json should be $expected; | |
end. | |
it "an annotated simple message" | |
$simple = new tests\Annotated\Simple(); | |
$simple->foo = 'FOO'; | |
$simple->bar = 1000; | |
$json = Protobuf::encode($simple); | |
$json. should. eq. '{"foo":"FOO","bar":1000}'; | |
end. | |
it "an annotated message with repeated fields" | |
$repeated = new \Tests\Annotated\Repeated(); | |
$repeated->string = array('one', 'two', 'three'); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '{"string":["one","two","three"]}'; | |
$repeated = new Tests\Annotated\Repeated(); | |
$repeated->int = array(1,2,3); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '{"int":[1,2,3]}'; | |
$repeated = new Tests\Annotated\Repeated(); | |
$repeated->nested = array(); | |
$nested = new Tests\Annotated\RepeatedNested(); | |
$nested->id = 1; | |
$repeated->nested[] = $nested; | |
$nested = new Tests\Annotated\RepeatedNested(); | |
$nested->id = 2; | |
$repeated->nested[] = $nested; | |
$nested = new Tests\Annotated\RepeatedNested(); | |
$nested->id = 3; | |
$repeated->nested[] = $nested; | |
$json = Protobuf::encode($repeated); | |
$json should eq '{"nested":[{"id":1},{"id":2},{"id":3}]}'; | |
end. | |
end; | |
describe "unserialize" | |
it "should unserialize a simple message" | |
$json = '{"string":"FOO","int32":1000}'; | |
$simple = Protobuf::decode('Tests\Simple', $json); | |
$simple should be instanceof 'Tests\Simple'; | |
$simple->string should equal 'FOO'; | |
$simple->int32 should equal 1000; | |
end. | |
it "a message with repeated fields" | |
$json = '{"string":["one","two","three"]}'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated->getString() should eq array('one', 'two', 'three'); | |
$json = '{"int":[1,2,3]}'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated should be instanceof 'Tests\Repeated'; | |
$repeated->getInt() should eq array(1,2,3); | |
$json = '{"nested":[{"id":1},{"id":2},{"id":3}]}'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated should be instanceof 'Tests\Repeated'; | |
foreach ($repeated->getNested() as $i=>$nested) { | |
$nested->getId() should eq ($i+1); | |
} | |
end. | |
it "a complex message" | |
$json = '{ | |
"person":[ | |
{ | |
"name":"John Doe", | |
"id":2051, | |
"email":"john.doe@gmail.com", | |
"phone":[ | |
{"number":"1231231212","type":1}, | |
{"number":"55512321312","type":0} | |
] | |
}, | |
{ | |
"name":"Iv\u00e1n Montes", | |
"id":23, | |
"email":"drslump@pollinimini.net", | |
"phone":[{"number":"3493123123","type":2}] | |
} | |
] | |
}'; | |
$json = preg_replace('/\n\s*/', '', $json); | |
$complex = Protobuf::decode('Tests\AddressBook', $json); | |
count($complex->person) should eq 2; | |
$complex->getPerson(0)->name should eq 'John Doe'; | |
$complex->getPerson(1)->name should eq 'Iván Montes'; | |
$complex->getPerson(0)->getPhone(1)->number should eq '55512321312'; | |
end. | |
end; | |
end; | |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/repeated.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
describe "JSON Indexed Codec" | |
before | |
Protobuf::setDefaultCodec(new Protobuf\Codec\JsonIndexed); | |
end | |
describe "serialize" | |
it "should serialize a simple message" | |
$simple = new Tests\Simple(); | |
$simple->string = 'FOO'; | |
$simple->int32 = 1000; | |
$json = Protobuf::encode($simple); | |
$json. should. eq. '["59",1000,"FOO"]'; | |
end. | |
it. "a message with repeated fields" | |
$repeated = new Tests\Repeated(); | |
$repeated->addString('one'); | |
$repeated->addString('two'); | |
$repeated->addString('three'); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '["1",["one","two","three"]]'; | |
$repeated = new Tests\Repeated(); | |
$repeated->addInt(1); | |
$repeated->addInt(2); | |
$repeated->addInt(3); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '["2",[1,2,3]]'; | |
$repeated = new Tests\Repeated(); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(1); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(2); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(3); | |
$repeated->addNested($nested); | |
$json = Protobuf::encode($repeated); | |
$json should eq '["3",[["1",1],["1",2],["1",3]]]'; | |
end. | |
it. "a complex message" | |
$book = new Tests\AddressBook(); | |
$person = new Tests\Person(); | |
$person->name = 'John Doe'; | |
$person->id = 2051; | |
$person->email = 'john.doe@gmail.com'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '1231231212'; | |
$phone->type = Tests\Person\PhoneType::HOME; | |
$person->addPhone($phone); | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '55512321312'; | |
$phone->type = Tests\Person\PhoneType::MOBILE; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$person = new Tests\Person(); | |
$person->name = 'Iván Montes'; | |
$person->id = 23; | |
$person->email = 'drslump@pollinimini.net'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '3493123123'; | |
$phone->type = Tests\Person\PhoneType::WORK; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$json = Protobuf::encode($book); | |
$expected = '[ | |
"1", | |
[ | |
[ | |
"1234", | |
"John Doe", | |
2051, | |
"john.doe@gmail.com", | |
[ | |
["12","1231231212",1], | |
["12","55512321312",0] | |
] | |
], | |
[ | |
"1234", | |
"Iv\u00e1n Montes", | |
23, | |
"drslump@pollinimini.net", | |
[ | |
["12","3493123123",2] | |
] | |
] | |
] | |
]'; | |
$expected = preg_replace('/\n\s*/', '', $expected); | |
$json should be $expected; | |
end. | |
end; | |
describe "unserialize" | |
it "should unserialize a simple message" | |
$json = '["59",1000,"FOO"]'; | |
$simple = Protobuf::decode('Tests\Simple', $json); | |
$simple should be instanceof 'Tests\Simple'; | |
$simple->string should equal 'FOO'; | |
$simple->int32 should equal 1000; | |
end. | |
it "a message with repeated fields" | |
$json = '["1",["one","two","three"]]'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated->getString() should eq array('one', 'two', 'three'); | |
$json = '["2",[1,2,3]]'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated should be instanceof 'Tests\Repeated'; | |
$repeated->getInt() should eq array(1,2,3); | |
$json = '["3",[["1",1],["1",2],["1",3]]]'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated should be instanceof 'Tests\Repeated'; | |
foreach ($repeated->getNested() as $i=>$nested) { | |
$nested->getId() should eq ($i+1); | |
} | |
end. | |
it "a complex message" | |
$json = '[ | |
"1", | |
[ | |
[ | |
"1234", | |
"John Doe", | |
2051, | |
"john.doe@gmail.com", | |
[ | |
["12","1231231212",1], | |
["12","55512321312",0] | |
] | |
], | |
[ | |
"1234", | |
"Iv\u00e1n Montes", | |
23, | |
"drslump@pollinimini.net", | |
[ | |
["12","3493123123",2] | |
] | |
] | |
] | |
]'; | |
$json = preg_replace('/\n\s*/', '', $json); | |
$complex = Protobuf::decode('Tests\AddressBook', $json); | |
count($complex->person) should eq 2; | |
$complex->getPerson(0)->name should eq 'John Doe'; | |
$complex->getPerson(1)->name should eq 'Iván Montes'; | |
$complex->getPerson(0)->getPhone(1)->number should eq '55512321312'; | |
end. | |
end; | |
end; | |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/repeated.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
describe "JSON TagMap Codec" | |
before | |
Protobuf::setDefaultCodec(new Protobuf\Codec\JsonTagMap); | |
end | |
describe "serialize" | |
it "should serialize a simple message" | |
$simple = new Tests\Simple(); | |
$simple->string = 'FOO'; | |
$simple->int32 = 1000; | |
$json = Protobuf::encode($simple); | |
$json. should. eq. '{"5":1000,"9":"FOO"}'; | |
end. | |
it. "a message with repeated fields" | |
$repeated = new Tests\Repeated(); | |
$repeated->addString('one'); | |
$repeated->addString('two'); | |
$repeated->addString('three'); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '{"1":["one","two","three"]}'; | |
$repeated = new Tests\Repeated(); | |
$repeated->addInt(1); | |
$repeated->addInt(2); | |
$repeated->addInt(3); | |
$bin = Protobuf::encode($repeated); | |
$bin should be '{"2":[1,2,3]}'; | |
$repeated = new Tests\Repeated(); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(1); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(2); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(3); | |
$repeated->addNested($nested); | |
$json = Protobuf::encode($repeated); | |
$json should eq '{"3":[{"1":1},{"1":2},{"1":3}]}'; | |
end. | |
it. "a complex message" | |
$book = new Tests\AddressBook(); | |
$person = new Tests\Person(); | |
$person->name = 'John Doe'; | |
$person->id = 2051; | |
$person->email = 'john.doe@gmail.com'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '1231231212'; | |
$phone->type = Tests\Person\PhoneType::HOME; | |
$person->addPhone($phone); | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '55512321312'; | |
$phone->type = Tests\Person\PhoneType::MOBILE; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$person = new Tests\Person(); | |
$person->name = 'Iván Montes'; | |
$person->id = 23; | |
$person->email = 'drslump@pollinimini.net'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '3493123123'; | |
$phone->type = Tests\Person\PhoneType::WORK; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$json = Protobuf::encode($book); | |
$expected = '{ | |
"1":[ | |
{ | |
"1":"John Doe", | |
"2":2051, | |
"3":"john.doe@gmail.com", | |
"4":[ | |
{"1":"1231231212","2":1}, | |
{"1":"55512321312","2":0} | |
] | |
}, | |
{ | |
"1":"Iv\u00e1n Montes", | |
"2":23, | |
"3":"drslump@pollinimini.net", | |
"4":[{"1":"3493123123","2":2}] | |
} | |
] | |
}'; | |
$expected = preg_replace('/\n\s*/', '', $expected); | |
$json should be $expected; | |
end. | |
end; | |
describe "unserialize" | |
it "should unserialize a simple message" | |
$json = '{"9":"FOO","5":1000}'; | |
$simple = Protobuf::decode('Tests\Simple', $json); | |
$simple should be instanceof 'Tests\Simple'; | |
$simple->string should equal 'FOO'; | |
$simple->int32 should equal 1000; | |
end. | |
it "a message with repeated fields" | |
$json = '{"1":["one","two","three"]}'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated->getString() should eq array('one', 'two', 'three'); | |
$json = '{"2":[1,2,3]}'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated should be instanceof 'Tests\Repeated'; | |
$repeated->getInt() should eq array(1,2,3); | |
$json = '{"3":[{"1":1},{"1":2},{"1":3}]}'; | |
$repeated = Protobuf::decode('Tests\Repeated', $json); | |
$repeated should be instanceof 'Tests\Repeated'; | |
foreach ($repeated->getNested() as $i=>$nested) { | |
$nested->getId() should eq ($i+1); | |
} | |
end. | |
it "a complex message" | |
$json = '{ | |
"1":[ | |
{ | |
"1":"John Doe", | |
"2":2051, | |
"3":"john.doe@gmail.com", | |
"4":[ | |
{"1":"1231231212","2":1}, | |
{"1":"55512321312","2":0} | |
] | |
}, | |
{ | |
"1":"Iv\u00e1n Montes", | |
"2":23, | |
"3":"drslump@pollinimini.net", | |
"4":[{"1":"3493123123","2":2}] | |
} | |
] | |
}'; | |
$json = preg_replace('/\n\s*/', '', $json); | |
$complex = Protobuf::decode('Tests\AddressBook', $json); | |
count($complex->person) should eq 2; | |
$complex->getPerson(0)->name should eq 'John Doe'; | |
$complex->getPerson(1)->name should eq 'Iván Montes'; | |
$complex->getPerson(0)->getPhone(1)->number should eq '55512321312'; | |
end. | |
end; | |
end; | |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/repeated.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
describe "TextFormat Codec" | |
before | |
Protobuf::setDefaultCodec(new ProtoBuf\Codec\TextFormat); | |
end | |
describe "serialize" | |
it "should serialize a simple message" | |
$simple = new Tests\Simple(); | |
$simple->string = 'FOO'; | |
$simple->int32 = 1000; | |
$txt = Protobuf::encode($simple); | |
$txt . should. be. "int32: 1000\nstring: \"FOO\"\n"; | |
end. | |
it. "a message with repeated fields" | |
$repeated = new \Tests\Repeated(); | |
$repeated->addString('one'); | |
$repeated->addString('two'); | |
$repeated->addString('three'); | |
$txt = Protobuf::encode($repeated); | |
$txt should be "string: \"one\"\nstring: \"two\"\nstring: \"three\"\n"; | |
$repeated = new Tests\Repeated(); | |
$repeated->addInt(1); | |
$repeated->addInt(2); | |
$repeated->addInt(3); | |
$txt = Protobuf::encode($repeated); | |
$txt should be "int: 1\nint: 2\nint: 3\n"; | |
$repeated = new Tests\Repeated(); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(1); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(2); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(3); | |
$repeated->addNested($nested); | |
$txt = Protobuf::encode($repeated); | |
$txt should eq "nested {\n id: 1\n}\nnested {\n id: 2\n}\nnested {\n id: 3\n}\n"; | |
end. | |
it. "a complex message" | |
$book = new Tests\AddressBook(); | |
$person = new Tests\Person(); | |
$person->name = 'John Doe'; | |
$person->id = 2051; | |
$person->email = 'john.doe@gmail.com'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '1231231212'; | |
$phone->type = Tests\Person\PhoneType::HOME; | |
$person->addPhone($phone); | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '55512321312'; | |
$phone->type = Tests\Person\PhoneType::MOBILE; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$person = new Tests\Person(); | |
$person->name = 'Iván Montes'; | |
$person->id = 23; | |
$person->email = 'drslump@pollinimini.net'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '3493123123'; | |
$phone->type = Tests\Person\PhoneType::WORK; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$txt = Protobuf::encode($book); | |
$txt = str_replace(' ', '', $txt); | |
$txt = trim($txt); | |
$expected = ' | |
person { | |
name: "John Doe" | |
id: 2051 | |
email: "john.doe@gmail.com" | |
phone { | |
number: "1231231212" | |
type: 1 | |
} | |
phone { | |
number: "55512321312" | |
type: 0 | |
} | |
} | |
person { | |
name: "Iv\u00e1n Montes" | |
id: 23 | |
email: "drslump@pollinimini.net" | |
phone { | |
number: "3493123123" | |
type: 2 | |
} | |
} | |
'; | |
$expected = str_replace(' ', '', $expected); | |
$expected = trim($expected); | |
$txt should be $expected; | |
end. | |
end; | |
describe "unserialize" | |
# throws \BadMethodCallException | |
it "TextFormat does not implement decoding" | |
$txt = "foo: \"FOO\"\nbar: \"BAR\"\n"; | |
$simple = Protobuf::decode('Tests\Simple', $txt); | |
end. | |
end; | |
end; | |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/repeated.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
describe "XML Codec" | |
before | |
Protobuf::setDefaultCodec(new ProtoBuf\Codec\Xml); | |
end | |
describe "serialize" | |
it "a simple message" | |
$simple = new Tests\Simple(); | |
$simple->string = 'FOO'; | |
$simple->int32 = 1000; | |
$xml = Protobuf::encode($simple); | |
$sxe = simplexml_load_string($xml); | |
$sxe->string should eq "FOO"; | |
$sxe->int32 should eq 1000; | |
end. | |
it. "a message with repeated fields" | |
$repeated = new \Tests\Repeated(); | |
$repeated->addString('one'); | |
$repeated->addString('two'); | |
$repeated->addString('three'); | |
$xml = Protobuf::encode($repeated); | |
$xml = simplexml_load_string($xml); | |
$xml->string[0] should eq 'one'; | |
$xml->string[1] should eq 'two'; | |
$xml->string[2] should eq 'three'; | |
$repeated = new Tests\Repeated(); | |
$repeated->addInt(1); | |
$repeated->addInt(2); | |
$repeated->addInt(3); | |
$xml = Protobuf::encode($repeated); | |
$xml = simplexml_load_string($xml); | |
$xml->int[0] should eq 1; | |
$xml->int[1] should eq 2; | |
$xml->int[2] should eq 3; | |
$repeated = new Tests\Repeated(); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(1); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(2); | |
$repeated->addNested($nested); | |
$nested = new Tests\Repeated\Nested(); | |
$nested->setId(3); | |
$repeated->addNested($nested); | |
$xml = Protobuf::encode($repeated); | |
$xml = simplexml_load_string($xml); | |
$xml->nested[0]->id should eq 1; | |
$xml->nested[1]->id should eq 2; | |
$xml->nested[2]->id should eq 3; | |
end. | |
it. "a complex message" | |
$book = new Tests\AddressBook(); | |
$person = new Tests\Person(); | |
$person->name = 'John Doe'; | |
$person->id = 2051; | |
$person->email = 'john.doe@gmail.com'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '1231231212'; | |
$phone->type = Tests\Person\PhoneType::HOME; | |
$person->addPhone($phone); | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '55512321312'; | |
$phone->type = Tests\Person\PhoneType::MOBILE; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$person = new Tests\Person(); | |
$person->name = 'Iván Montes'; | |
$person->id = 23; | |
$person->email = 'drslump@pollinimini.net'; | |
$phone = new Tests\Person\PhoneNumber; | |
$phone->number = '3493123123'; | |
$phone->type = Tests\Person\PhoneType::WORK; | |
$person->addPhone($phone); | |
$book->addPerson($person); | |
$xml = Protobuf::encode($book); | |
$xml = simplexml_load_string($xml); | |
$xml->person[0]->name should eq "John Doe"; | |
$xml->person[0]->phone[1]->number should eq "55512321312"; | |
$xml->person[1]->id should eq 23; | |
$xml->person[1]->phone[0]->type should eq 2; | |
end. | |
end; | |
describe "unserialize" | |
it "should unserialize a simple message" | |
$xml = new SimpleXmlElement('<root></root>'); | |
$xml->addChild('string', 'FOO'); | |
$xml->addChild('int32', 1000); | |
$simple = Protobuf::decode('Tests\Simple', $xml); | |
$simple should be instanceof 'Tests\Simple'; | |
$simple->string should equal 'FOO'; | |
$simple->int32 should equal 1000; | |
end. | |
it "a message with repeated fields" | |
$xml = new SimpleXMLElement('<root></root>'); | |
$xml->addChild('string', 'one'); | |
$xml->addChild('string', 'two'); | |
$xml->addChild('string', 'three'); | |
$repeated = Protobuf::decode('Tests\Repeated', $xml); | |
$repeated->getString() should eq array('one', 'two', 'three'); | |
$xml = new SimpleXMLElement('<root></root>'); | |
$xml->addChild('int', 1); | |
$xml->addChild('int', 2); | |
$xml->addChild('int', 3); | |
$repeated = Protobuf::decode('Tests\Repeated', $xml); | |
$repeated should be instanceof 'Tests\Repeated'; | |
$repeated->getInt() should eq array(1,2,3); | |
$xml = new SimpleXMLElement('<root></root>'); | |
$xml->addChild('nested')->addChild('id', 1); | |
$xml->addChild('nested')->addChild('id', 2); | |
$xml->addChild('nested')->addChild('id', 3); | |
$repeated = Protobuf::decode('Tests\Repeated', $xml); | |
$repeated should be instanceof 'Tests\Repeated'; | |
foreach ($repeated->getNested() as $i=>$nested) { | |
$nested->getId() should eq ($i+1); | |
} | |
end. | |
it "a complex message" | |
$xml = new SimpleXMLElement('<root></root>'); | |
$p = $xml->addChild('person'); | |
$p->addChild('name', 'John Doe'); | |
$p->addChild('id', 2051); | |
$p->addChild('email', 'john.doe@gmail.com'); | |
$p = $p->addChild('phone'); | |
$p->addChild('number', '1231231212'); | |
$p->addChild('type', 1); | |
$p = $xml->addChild('person'); | |
$p->addChild('name', 'Iván Montes'); | |
$p->addChild('id', 23); | |
$p->addChild('email', 'drslump@pollinimini.net'); | |
$p = $p->addChild('phone'); | |
$p->addChild('number', '3493123123'); | |
$p->addChild('type', 2); | |
$complex = Protobuf::decode('Tests\AddressBook', $xml->asXML()); | |
count($complex->person) should eq 2; | |
$complex->getPerson(0)->name should eq 'John Doe'; | |
$complex->getPerson(1)->name should eq 'Iván Montes'; | |
$complex->getPerson(1)->getPhone(0)->number should eq '3493123123'; | |
end. | |
end; | |
end; | |
<?php | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use DrSlump\Protobuf; | |
describe 'Protobuf' | |
//before | |
Protobuf::autoload(); | |
//end | |
it 'should autoload classes' | |
new Protobuf\Codec\Binary(); | |
end. | |
describe 'codecs registry' | |
it 'should get a default codec if none set' | |
$codec = Protobuf::getCodec(); | |
$codec should be an instance of '\DrSlump\Protobuf\CodecInterface'; | |
end. | |
it 'should return the passed codec instance' | |
$passed = new Protobuf\Codec\Binary(); | |
$getted = Protobuf::getCodec($passed); | |
$getted should be $passed | |
end. | |
it. 'should register a new codec' | |
$setted = new Protobuf\Codec\Binary(); | |
Protobuf::registerCodec('test', $setted); | |
$getted = Protobuf::getCodec('test'); | |
$getted should be $setted | |
end. | |
it 'should register a new default codec' | |
$setted = new Protobuf\Codec\Binary(); | |
Protobuf::setDefaultCodec($setted); | |
Protobuf::getCodec() should be $setted | |
end. | |
# throws DrSlump\Protobuf\Exception | |
it. 'should unregister a codec' | |
$setted = new Protobuf\Codec\Binary(); | |
Protobuf::registerCodec('test', $setted); | |
$result = Protobuf::unregisterCodec('test'); | |
$result should be true; | |
// If not set throws an exception | |
Protobuf::getCodec('test'); | |
end. | |
it. 'should unregister the default codec' | |
$result = Protobuf::unregisterCodec('default'); | |
$result should be true; | |
// Ensure a new default is given | |
$getted = Protobuf::getCodec(); | |
$getted should be instanceof 'DrSlump\Protobuf\Codec\Binary' | |
end. | |
end; | |
end; | |
<?php | |
require_once 'Benchmark/Profiler.php'; | |
require_once __DIR__ . '/../library/DrSlump/Protobuf.php'; | |
use \DrSlump\Protobuf; | |
Protobuf::autoload(); | |
include_once __DIR__ . '/protos/simple.php'; | |
include_once __DIR__ . '/protos/addressbook.php'; | |
class Benchmark { | |
protected $tests = array( | |
'DecodeBinarySimple', | |
'DecodeJsonSimple', | |
); | |
public function run($iterations = 1000) | |
{ | |
$profiler = new Benchmark_Profiler(true); | |
foreach ($this->tests as $test) { | |
$method = 'config' . $test; | |
$args = $this->$method(); | |
$method = 'run' . $test; | |
$profiler->enterSection($test); | |
for ($i=0; $i<$iterations; $i++) { | |
call_user_func_array(array($this, $method), $args); | |
} | |
$profiler->leaveSection($test); | |
} | |
$profiler->stop(); | |
$profiler->display(); | |
} | |
protected function configDecodeBinarySimple() | |
{ | |
return array( | |
new Protobuf\Codec\Binary(), | |
file_get_contents(__DIR__ . '/protos/simple.bin') | |
); | |
} | |
protected function runDecodeBinarySimple($codec, $data) | |
{ | |
$codec->decode(new tests\Simple(), $data); | |
} | |
protected function configDecodeJsonSimple() | |
{ | |
$codecBin = new Protobuf\Codec\Binary(); | |
$codecJson = new Protobuf\Codec\Json(); | |
$bin = $this->configDecodeBinarySimple(); | |
$simple = $codecBin->decode(new tests\Simple(), $bin[1]); | |
$data = $codecJson->encode($simple); | |
return array($codecJson, $data); | |
} | |
protected function runDecodeJsonSimple($codec, $data) | |
{ | |
$codec->decode(new tests\Simple(), $data); | |
} | |
} | |
$bench = new Benchmark(); | |
$bench->run(1000); | |
<?php | |
/** | |
* Created by IntelliJ IDEA. | |
* User: drslump | |
* Date: 6/27/11 | |
* Time: 12:48 AM | |
* To change this template use File | Settings | File Templates. | |
*/ | |
<?php | |
namespace Tests\Annotated; | |
class Repeated extends \DrSlump\Protobuf\AnnotatedMessage | |
{ | |
/** @protobuf(tag=1, type=string, repeated) */ | |
public $string; | |
/** @protobuf(tag=2, type=int32, repeated) */ | |
public $int; | |
/** @protobuf(tag=3, type=message, reference=tests\Annotated\RepeatedNested, repeated) */ | |
public $nested; | |
} | |
class RepeatedNested extends \DrSlump\Protobuf\AnnotatedMessage | |
{ | |
/** @protobuf(tag=1, type=int32) */ | |
public $id; | |
} | |
<?php | |
namespace Tests\Annotated; | |
class Simple extends \DrSlump\Protobuf\AnnotatedMessage | |
{ | |
/** @protobuf(tag=1, type=string, required) */ | |
public $foo; | |
/** @protobuf(tag=2, type=int32, required) */ | |
public $bar; | |
/** @protobuf(tag=3, type=string, optional) */ | |
public $baz; | |
} | |
Binary files /dev/null and b/lib/Protobuf-PHP/tests/protos/addressbook.bin differ
<?php | |
// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@ | |
// Source: addressbook.proto | |
// Date: 2011-04-13 17:07:17 | |
namespace tests { | |
class Person extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Person'); | |
// required name = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "name"; | |
$f->type = 9; | |
$f->rule = 2; | |
$descriptor->addField($f); | |
// required id = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "id"; | |
$f->type = 5; | |
$f->rule = 2; | |
$descriptor->addField($f); | |
// optional email = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "email"; | |
$f->type = 9; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
// repeated .tests.Person.PhoneNumber phone = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "phone"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\tests\Person\PhoneNumber'; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
return $descriptor; | |
} | |
/** @var string */ | |
public $name = null; | |
/** @var int */ | |
public $id = null; | |
/** @var string */ | |
public $email = null; | |
/** @var \tests\Person\PhoneNumber[] */ | |
public $phone = array(); | |
/** | |
* Check if <name> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasName(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <name> value | |
* | |
* @return \tests\Person | |
*/ | |
public function clearName(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <name> value | |
* | |
* @return string | |
*/ | |
public function getName(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <name> value | |
* | |
* @param string $value | |
* @return \tests\Person | |
*/ | |
public function setName( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasId(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <id> value | |
* | |
* @return \tests\Person | |
*/ | |
public function clearId(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <id> value | |
* | |
* @return int | |
*/ | |
public function getId(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <id> value | |
* | |
* @param int $value | |
* @return \tests\Person | |
*/ | |
public function setId( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <email> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasEmail(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <email> value | |
* | |
* @return \tests\Person | |
*/ | |
public function clearEmail(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <email> value | |
* | |
* @return string | |
*/ | |
public function getEmail(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <email> value | |
* | |
* @param string $value | |
* @return \tests\Person | |
*/ | |
public function setEmail( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <phone> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPhone(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <phone> value | |
* | |
* @return \tests\Person | |
*/ | |
public function clearPhone(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <phone> value | |
* | |
* @param int $idx | |
* @return \tests\Person\PhoneNumber | |
*/ | |
public function getPhone($idx = NULL){ | |
return $this->_get(4, $idx); | |
} | |
/** | |
* Set <phone> value | |
* | |
* @param \tests\Person\PhoneNumber $value | |
* @return \tests\Person | |
*/ | |
public function setPhone(\tests\Person\PhoneNumber $value, $idx = NULL){ | |
return $this->_set(4, $value, $idx); | |
} | |
/** | |
* Get all elements of <phone> | |
* | |
* @return \tests\Person\PhoneNumber[] | |
*/ | |
public function getPhoneList(){ | |
return $this->_get(4); | |
} | |
/** | |
* Add a new element to <phone> | |
* | |
* @param \tests\Person\PhoneNumber $value | |
* @return \tests\Person | |
*/ | |
public function addPhone(\tests\Person\PhoneNumber $value){ | |
return $this->_add(4, $value); | |
} | |
} | |
} | |
namespace tests\Person { | |
class PhoneType { | |
const MOBILE = 0; | |
const HOME = 1; | |
const WORK = 2; | |
} | |
} | |
namespace tests\Person { | |
class PhoneNumber extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Person\PhoneNumber'); | |
// required number = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "number"; | |
$f->type = 9; | |
$f->rule = 2; | |
$descriptor->addField($f); | |
// optional .tests.Person.PhoneType type = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "type"; | |
$f->type = 14; | |
$f->rule = 1; | |
$f->reference = '\tests\Person\PhoneType'; | |
$f->default = \tests\Person\PhoneType::HOME; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
return $descriptor; | |
} | |
/** @var string */ | |
public $number = null; | |
/** @var int - \tests\Person\PhoneType */ | |
public $type = \tests\Person\PhoneType::HOME; | |
/** | |
* Check if <number> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNumber(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <number> value | |
* | |
* @return \tests\Person\PhoneNumber | |
*/ | |
public function clearNumber(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <number> value | |
* | |
* @return string | |
*/ | |
public function getNumber(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <number> value | |
* | |
* @param string $value | |
* @return \tests\Person\PhoneNumber | |
*/ | |
public function setNumber( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <type> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasType(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <type> value | |
* | |
* @return \tests\Person\PhoneNumber | |
*/ | |
public function clearType(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <type> value | |
* | |
* @return int - \tests\Person\PhoneType | |
*/ | |
public function getType(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <type> value | |
* | |
* @param int - \tests\Person\PhoneType $value | |
* @return \tests\Person\PhoneNumber | |
*/ | |
public function setType( $value){ | |
return $this->_set(2, $value); | |
} | |
} | |
} | |
namespace tests { | |
class AddressBook extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor('\tests\AddressBook'); | |
// repeated .tests.Person person = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "person"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\tests\Person'; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
return $descriptor; | |
} | |
/** @var \tests\Person[] */ | |
public $person = array(); | |
/** | |
* Check if <person> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasPerson(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <person> value | |
* | |
* @return \tests\AddressBook | |
*/ | |
public function clearPerson(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <person> value | |
* | |
* @param int $idx | |
* @return \tests\Person | |
*/ | |
public function getPerson($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <person> value | |
* | |
* @param \tests\Person $value | |
* @return \tests\AddressBook | |
*/ | |
public function setPerson(\tests\Person $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <person> | |
* | |
* @return \tests\Person[] | |
*/ | |
public function getPersonList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <person> | |
* | |
* @param \tests\Person $value | |
* @return \tests\AddressBook | |
*/ | |
public function addPerson(\tests\Person $value){ | |
return $this->_add(1, $value); | |
} | |
} | |
} | |
import "php.proto"; | |
package tests; | |
//option (php.namespace) = "Example"; | |
//option (php.multifile) = true; | |
/** | |
* Defines a Person in the addressbook | |
*/ | |
message Person { | |
/* The full name of the person */ | |
required string name = 1; | |
/* The person Id in the database */ | |
required int32 id = 2; | |
/* The person email */ | |
optional string email = 3; | |
/* Different types of phones */ | |
enum PhoneType { | |
MOBILE = 0; | |
HOME = 1; | |
WORK = 2; | |
} | |
/* | |
A phone number record | |
*/ | |
message PhoneNumber { | |
required string number = 1; | |
optional PhoneType type = 2 [default = HOME]; | |
} | |
/* The different phone numbers associated to a person */ | |
repeated PhoneNumber phone = 4; | |
} | |
/* A collection of persons contact details */ | |
message AddressBook { | |
repeated Person person = 1; | |
extensions 1000 to max; | |
} | |
person { | |
name: "John Doe" | |
id: 2051 | |
email: "john.doe@gmail.com" | |
phone { | |
number: "1231231212" | |
type: HOME | |
} | |
phone { | |
number: "55512321312" | |
type: MOBILE | |
} | |
} | |
person { | |
name: "Iván Montes" | |
id: 23 | |
email: "drslump@pollinimini.net" | |
phone { | |
number: "3493123123" | |
type: WORK | |
} | |
} | |
int: 1 | |
int: 2 | |
int: 3 | |
nested { | |
id: 1 | |
} | |
nested { | |
id: 2 | |
} | |
nested { | |
id: 3 | |
} | |
one | |
two | |
three |
string: "one" | |
string: "two" | |
string: "three" | |
<?php | |
// DO NOT EDIT! Generated by Protobuf for PHP protoc plugin @package_version@ | |
// Source: repeated.proto | |
// Date: 2011-04-12 14:07:42 | |
namespace tests { | |
class Repeated extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Repeated'); | |
// repeated string = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "string"; | |
$f->type = 9; | |
$f->rule = 3; | |
$descriptor->addField($f); | |
// repeated int = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "int"; | |
$f->type = 5; | |
$f->rule = 3; | |
$descriptor->addField($f); | |
// repeated .tests.Repeated.Nested nested = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "nested"; | |
$f->type = 11; | |
$f->rule = 3; | |
$f->reference = '\tests\Repeated\Nested'; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
return $descriptor; | |
} | |
/** @var string[] */ | |
public $string = array(); | |
/** @var int[] */ | |
public $int = array(); | |
/** @var \tests\Repeated\Nested[] */ | |
public $nested = array(); | |
/** | |
* Check if <string> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasString(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <string> value | |
* | |
* @return \tests\Repeated | |
*/ | |
public function clearString(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <string> value | |
* | |
* @param int $idx | |
* @return string | |
*/ | |
public function getString($idx = NULL){ | |
return $this->_get(1, $idx); | |
} | |
/** | |
* Set <string> value | |
* | |
* @param string $value | |
* @return \tests\Repeated | |
*/ | |
public function setString( $value, $idx = NULL){ | |
return $this->_set(1, $value, $idx); | |
} | |
/** | |
* Get all elements of <string> | |
* | |
* @return string[] | |
*/ | |
public function getStringList(){ | |
return $this->_get(1); | |
} | |
/** | |
* Add a new element to <string> | |
* | |
* @param string $value | |
* @return \tests\Repeated | |
*/ | |
public function addString( $value){ | |
return $this->_add(1, $value); | |
} | |
/** | |
* Check if <int> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasInt(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <int> value | |
* | |
* @return \tests\Repeated | |
*/ | |
public function clearInt(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <int> value | |
* | |
* @param int $idx | |
* @return int | |
*/ | |
public function getInt($idx = NULL){ | |
return $this->_get(2, $idx); | |
} | |
/** | |
* Set <int> value | |
* | |
* @param int $value | |
* @return \tests\Repeated | |
*/ | |
public function setInt( $value, $idx = NULL){ | |
return $this->_set(2, $value, $idx); | |
} | |
/** | |
* Get all elements of <int> | |
* | |
* @return int[] | |
*/ | |
public function getIntList(){ | |
return $this->_get(2); | |
} | |
/** | |
* Add a new element to <int> | |
* | |
* @param int $value | |
* @return \tests\Repeated | |
*/ | |
public function addInt( $value){ | |
return $this->_add(2, $value); | |
} | |
/** | |
* Check if <nested> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasNested(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <nested> value | |
* | |
* @return \tests\Repeated | |
*/ | |
public function clearNested(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <nested> value | |
* | |
* @param int $idx | |
* @return \tests\Repeated\Nested | |
*/ | |
public function getNested($idx = NULL){ | |
return $this->_get(3, $idx); | |
} | |
/** | |
* Set <nested> value | |
* | |
* @param \tests\Repeated\Nested $value | |
* @return \tests\Repeated | |
*/ | |
public function setNested(\tests\Repeated\Nested $value, $idx = NULL){ | |
return $this->_set(3, $value, $idx); | |
} | |
/** | |
* Get all elements of <nested> | |
* | |
* @return \tests\Repeated\Nested[] | |
*/ | |
public function getNestedList(){ | |
return $this->_get(3); | |
} | |
/** | |
* Add a new element to <nested> | |
* | |
* @param \tests\Repeated\Nested $value | |
* @return \tests\Repeated | |
*/ | |
public function addNested(\tests\Repeated\Nested $value){ | |
return $this->_add(3, $value); | |
} | |
} | |
} | |
namespace tests\Repeated { | |
class Nested extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor(\DrSlump\Protobuf\Descriptor $descriptor = NULL) | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Repeated\Nested'); | |
// optional id = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "id"; | |
$f->type = 5; | |
$f->rule = 1; | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
return $descriptor; | |
} | |
/** @var int */ | |
public $id = null; | |
/** | |
* Check if <id> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasId(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <id> value | |
* | |
* @return \tests\Repeated\Nested | |
*/ | |
public function clearId(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <id> value | |
* | |
* @return int | |
*/ | |
public function getId(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <id> value | |
* | |
* @param int $value | |
* @return \tests\Repeated\Nested | |
*/ | |
public function setId( $value){ | |
return $this->_set(1, $value); | |
} | |
} | |
} | |
package tests; | |
message Repeated { | |
message Nested { | |
optional int32 id = 1; | |
} | |
repeated string string = 1; | |
repeated int32 int = 2; | |
repeated Nested nested = 3; | |
} | |
<?php | |
// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin @package_version@ | |
// Source: simple.proto | |
// Date: 2011-07-10 10:05:44 | |
// @@protoc_insertion_point(scope_file) | |
namespace tests { | |
// @@protoc_insertion_point(scope_namespace) | |
// @@protoc_insertion_point(namespace_tests) | |
class Simple extends \DrSlump\Protobuf\Message { | |
/** @var \Closure[] */ | |
protected static $__extensions = array(); | |
public static function descriptor() | |
{ | |
$descriptor = new \DrSlump\Protobuf\Descriptor('\tests\Simple'); | |
// optional double = 1 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 1; | |
$f->name = "double"; | |
$f->type = 1; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:double) | |
$descriptor->addField($f); | |
// optional float = 2 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 2; | |
$f->name = "float"; | |
$f->type = 2; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:float) | |
$descriptor->addField($f); | |
// optional int64 = 3 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 3; | |
$f->name = "int64"; | |
$f->type = 3; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:int64) | |
$descriptor->addField($f); | |
// optional uint64 = 4 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 4; | |
$f->name = "uint64"; | |
$f->type = 4; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:uint64) | |
$descriptor->addField($f); | |
// optional int32 = 5 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 5; | |
$f->name = "int32"; | |
$f->type = 5; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:int32) | |
$descriptor->addField($f); | |
// optional fixed64 = 6 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 6; | |
$f->name = "fixed64"; | |
$f->type = 6; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:fixed64) | |
$descriptor->addField($f); | |
// optional fixed32 = 7 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 7; | |
$f->name = "fixed32"; | |
$f->type = 7; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:fixed32) | |
$descriptor->addField($f); | |
// optional bool = 8 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 8; | |
$f->name = "bool"; | |
$f->type = 8; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:bool) | |
$descriptor->addField($f); | |
// optional string = 9 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 9; | |
$f->name = "string"; | |
$f->type = 9; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:string) | |
$descriptor->addField($f); | |
// optional bytes = 12 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 12; | |
$f->name = "bytes"; | |
$f->type = 12; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:bytes) | |
$descriptor->addField($f); | |
// optional uint32 = 13 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 13; | |
$f->name = "uint32"; | |
$f->type = 13; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:uint32) | |
$descriptor->addField($f); | |
// optional sfixed32 = 15 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 15; | |
$f->name = "sfixed32"; | |
$f->type = 15; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:sfixed32) | |
$descriptor->addField($f); | |
// optional sfixed64 = 16 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 16; | |
$f->name = "sfixed64"; | |
$f->type = 16; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:sfixed64) | |
$descriptor->addField($f); | |
// optional sint32 = 17 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 17; | |
$f->name = "sint32"; | |
$f->type = 17; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:sint32) | |
$descriptor->addField($f); | |
// optional sint64 = 18 | |
$f = new \DrSlump\Protobuf\Field(); | |
$f->number = 18; | |
$f->name = "sint64"; | |
$f->type = 18; | |
$f->rule = 1; | |
// @@protoc_insertion_point(scope_field) | |
// @@protoc_insertion_point(field_tests.Simple:sint64) | |
$descriptor->addField($f); | |
foreach (self::$__extensions as $cb) { | |
$descriptor->addField($cb(), true); | |
} | |
// @@protoc_insertion_point(scope_descriptor) | |
// @@protoc_insertion_point(descriptor_tests.Simple) | |
return $descriptor; | |
} | |
/** @var float */ | |
public $double = null; | |
/** @var float */ | |
public $float = null; | |
/** @var int */ | |
public $int64 = null; | |
/** @var int */ | |
public $uint64 = null; | |
/** @var int */ | |
public $int32 = null; | |
/** @var int */ | |
public $fixed64 = null; | |
/** @var int */ | |
public $fixed32 = null; | |
/** @var boolean */ | |
public $bool = null; | |
/** @var string */ | |
public $string = null; | |
/** @var string */ | |
public $bytes = null; | |
/** @var int */ | |
public $uint32 = null; | |
/** @var int */ | |
public $sfixed32 = null; | |
/** @var int */ | |
public $sfixed64 = null; | |
/** @var int */ | |
public $sint32 = null; | |
/** @var int */ | |
public $sint64 = null; | |
/** | |
* Check if <double> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasDouble(){ | |
return $this->_has(1); | |
} | |
/** | |
* Clear <double> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearDouble(){ | |
return $this->_clear(1); | |
} | |
/** | |
* Get <double> value | |
* | |
* @return float | |
*/ | |
public function getDouble(){ | |
return $this->_get(1); | |
} | |
/** | |
* Set <double> value | |
* | |
* @param float $value | |
* @return \tests\Simple | |
*/ | |
public function setDouble( $value){ | |
return $this->_set(1, $value); | |
} | |
/** | |
* Check if <float> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasFloat(){ | |
return $this->_has(2); | |
} | |
/** | |
* Clear <float> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearFloat(){ | |
return $this->_clear(2); | |
} | |
/** | |
* Get <float> value | |
* | |
* @return float | |
*/ | |
public function getFloat(){ | |
return $this->_get(2); | |
} | |
/** | |
* Set <float> value | |
* | |
* @param float $value | |
* @return \tests\Simple | |
*/ | |
public function setFloat( $value){ | |
return $this->_set(2, $value); | |
} | |
/** | |
* Check if <int64> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasInt64(){ | |
return $this->_has(3); | |
} | |
/** | |
* Clear <int64> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearInt64(){ | |
return $this->_clear(3); | |
} | |
/** | |
* Get <int64> value | |
* | |
* @return int | |
*/ | |
public function getInt64(){ | |
return $this->_get(3); | |
} | |
/** | |
* Set <int64> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setInt64( $value){ | |
return $this->_set(3, $value); | |
} | |
/** | |
* Check if <uint64> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUint64(){ | |
return $this->_has(4); | |
} | |
/** | |
* Clear <uint64> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearUint64(){ | |
return $this->_clear(4); | |
} | |
/** | |
* Get <uint64> value | |
* | |
* @return int | |
*/ | |
public function getUint64(){ | |
return $this->_get(4); | |
} | |
/** | |
* Set <uint64> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setUint64( $value){ | |
return $this->_set(4, $value); | |
} | |
/** | |
* Check if <int32> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasInt32(){ | |
return $this->_has(5); | |
} | |
/** | |
* Clear <int32> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearInt32(){ | |
return $this->_clear(5); | |
} | |
/** | |
* Get <int32> value | |
* | |
* @return int | |
*/ | |
public function getInt32(){ | |
return $this->_get(5); | |
} | |
/** | |
* Set <int32> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setInt32( $value){ | |
return $this->_set(5, $value); | |
} | |
/** | |
* Check if <fixed64> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasFixed64(){ | |
return $this->_has(6); | |
} | |
/** | |
* Clear <fixed64> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearFixed64(){ | |
return $this->_clear(6); | |
} | |
/** | |
* Get <fixed64> value | |
* | |
* @return int | |
*/ | |
public function getFixed64(){ | |
return $this->_get(6); | |
} | |
/** | |
* Set <fixed64> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setFixed64( $value){ | |
return $this->_set(6, $value); | |
} | |
/** | |
* Check if <fixed32> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasFixed32(){ | |
return $this->_has(7); | |
} | |
/** | |
* Clear <fixed32> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearFixed32(){ | |
return $this->_clear(7); | |
} | |
/** | |
* Get <fixed32> value | |
* | |
* @return int | |
*/ | |
public function getFixed32(){ | |
return $this->_get(7); | |
} | |
/** | |
* Set <fixed32> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setFixed32( $value){ | |
return $this->_set(7, $value); | |
} | |
/** | |
* Check if <bool> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasBool(){ | |
return $this->_has(8); | |
} | |
/** | |
* Clear <bool> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearBool(){ | |
return $this->_clear(8); | |
} | |
/** | |
* Get <bool> value | |
* | |
* @return boolean | |
*/ | |
public function getBool(){ | |
return $this->_get(8); | |
} | |
/** | |
* Set <bool> value | |
* | |
* @param boolean $value | |
* @return \tests\Simple | |
*/ | |
public function setBool( $value){ | |
return $this->_set(8, $value); | |
} | |
/** | |
* Check if <string> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasString(){ | |
return $this->_has(9); | |
} | |
/** | |
* Clear <string> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearString(){ | |
return $this->_clear(9); | |
} | |
/** | |
* Get <string> value | |
* | |
* @return string | |
*/ | |
public function getString(){ | |
return $this->_get(9); | |
} | |
/** | |
* Set <string> value | |
* | |
* @param string $value | |
* @return \tests\Simple | |
*/ | |
public function setString( $value){ | |
return $this->_set(9, $value); | |
} | |
/** | |
* Check if <bytes> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasBytes(){ | |
return $this->_has(12); | |
} | |
/** | |
* Clear <bytes> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearBytes(){ | |
return $this->_clear(12); | |
} | |
/** | |
* Get <bytes> value | |
* | |
* @return string | |
*/ | |
public function getBytes(){ | |
return $this->_get(12); | |
} | |
/** | |
* Set <bytes> value | |
* | |
* @param string $value | |
* @return \tests\Simple | |
*/ | |
public function setBytes( $value){ | |
return $this->_set(12, $value); | |
} | |
/** | |
* Check if <uint32> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasUint32(){ | |
return $this->_has(13); | |
} | |
/** | |
* Clear <uint32> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearUint32(){ | |
return $this->_clear(13); | |
} | |
/** | |
* Get <uint32> value | |
* | |
* @return int | |
*/ | |
public function getUint32(){ | |
return $this->_get(13); | |
} | |
/** | |
* Set <uint32> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setUint32( $value){ | |
return $this->_set(13, $value); | |
} | |
/** | |
* Check if <sfixed32> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSfixed32(){ | |
return $this->_has(15); | |
} | |
/** | |
* Clear <sfixed32> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearSfixed32(){ | |
return $this->_clear(15); | |
} | |
/** | |
* Get <sfixed32> value | |
* | |
* @return int | |
*/ | |
public function getSfixed32(){ | |
return $this->_get(15); | |
} | |
/** | |
* Set <sfixed32> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setSfixed32( $value){ | |
return $this->_set(15, $value); | |
} | |
/** | |
* Check if <sfixed64> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSfixed64(){ | |
return $this->_has(16); | |
} | |
/** | |
* Clear <sfixed64> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearSfixed64(){ | |
return $this->_clear(16); | |
} | |
/** | |
* Get <sfixed64> value | |
* | |
* @return int | |
*/ | |
public function getSfixed64(){ | |
return $this->_get(16); | |
} | |
/** | |
* Set <sfixed64> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setSfixed64( $value){ | |
return $this->_set(16, $value); | |
} | |
/** | |
* Check if <sint32> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSint32(){ | |
return $this->_has(17); | |
} | |
/** | |
* Clear <sint32> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearSint32(){ | |
return $this->_clear(17); | |
} | |
/** | |
* Get <sint32> value | |
* | |
* @return int | |
*/ | |
public function getSint32(){ | |
return $this->_get(17); | |
} | |
/** | |
* Set <sint32> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setSint32( $value){ | |
return $this->_set(17, $value); | |
} | |
/** | |
* Check if <sint64> has a value | |
* | |
* @return boolean | |
*/ | |
public function hasSint64(){ | |
return $this->_has(18); | |
} | |
/** | |
* Clear <sint64> value | |
* | |
* @return \tests\Simple | |
*/ | |
public function clearSint64(){ | |
return $this->_clear(18); | |
} | |
/** | |
* Get <sint64> value | |
* | |
* @return int | |
*/ | |
public function getSint64(){ | |
return $this->_get(18); | |
} | |
/** | |
* Set <sint64> value | |
* | |
* @param int $value | |
* @return \tests\Simple | |
*/ | |
public function setSint64( $value){ | |
return $this->_set(18, $value); | |
} | |
// @@protoc_insertion_point(scope_class) | |
// @@protoc_insertion_point(class_tests.Simple) | |
} | |
} | |
package tests; | |
message Simple { | |
optional double double = 1; | |
optional float float = 2; | |
optional int64 int64 = 3; | |
optional uint64 uint64 = 4; | |
optional int32 int32 = 5; | |
optional fixed64 fixed64 = 6; | |
optional fixed32 fixed32 = 7; | |
optional bool bool = 8; | |
optional string string = 9; | |
optional bytes bytes = 12; | |
optional uint32 uint32 = 13; | |
optional sfixed32 sfixed32 = 15; | |
optional sfixed64 sfixed64 = 16; | |
optional sint32 sint32 = 17; | |
optional sint64 sint64 = 18; | |
} | |
double: 123456789.12345 | |
float: 12345.123 | |
int64: -123456789123456789 | |
uint64: 123456789123456789 | |
int32: -123456789 | |
fixed64: 123456789123456789 | |
fixed32: 123456789 | |
bool: 1 | |
string: "foo" | |
bytes: "bar" | |
uint32: 123456789 | |
sfixed32: -123456789 | |
sfixed64: -123456789123456789 | |
sint32: -123456789 | |
sint64: -123456789123456789 | |
<?php | <?php |
include ("../include/common.inc.php"); | include ("../include/common.inc.php"); |
$result = Array(); | $result = Array(); |
if (isset($_REQUEST['term'])) { | if (isset($_REQUEST['term'])) { |
$term = filter_var($_REQUEST['term'], FILTER_SANITIZE_STRING); | $term = filter_var($_REQUEST['term'], FILTER_SANITIZE_STRING); |
$query = "Select stop_name,min(stop_lat) as stop_lat,min(stop_lon) as stop_lon from stops where stop_name LIKE :term group by stop_name"; | $query = "Select stop_name,min(stop_lat) as stop_lat,min(stop_lon) as stop_lon from stops where stop_name ILIKE :term group by stop_name"; |
$query = $conn->prepare($query); | $query = $conn->prepare($query); |
$term = "$term%"; | $term = "$term%"; |
$query->bindParam(":term", $term); | $query->bindParam(":term", $term); |
$query->execute(); | $query->execute(); |
if (!$query) { | if (!$query) { |
databaseError($conn->errorInfo()); | databaseError($conn->errorInfo()); |
return Array(); | return Array(); |
} | } |
foreach ($query->fetchAll() as $row) { | foreach ($query->fetchAll() as $row) { |
$name = $row['stop_name'] . " (" . $row['stop_lat'] . "," . $row['stop_lon'] . ")"; | $name = $row['stop_name'] . " (" . $row['stop_lat'] . "," . $row['stop_lon'] . ")"; |
$result[] = Array( | $result[] = Array( |
"id" => $name, | "id" => $name, |
"label" => $name, | "label" => $name, |
"value" => $name | "value" => $name |
); | ); |
} | } |
} | } |
echo json_encode($result); | echo json_encode($result); |
?> | ?> |
<?php | |
/** | |
* This is the PHP OpenID library by JanRain, Inc. | |
* | |
* This module contains core utility functionality used by the | |
* library. See Consumer.php and Server.php for the consumer and | |
* server implementations. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* The library version string | |
*/ | |
define('Auth_OpenID_VERSION', '2.2.2'); | |
/** | |
* Require the fetcher code. | |
*/ | |
require_once "Auth/Yadis/PlainHTTPFetcher.php"; | |
require_once "Auth/Yadis/ParanoidHTTPFetcher.php"; | |
require_once "Auth/OpenID/BigMath.php"; | |
require_once "Auth/OpenID/URINorm.php"; | |
/** | |
* Status code returned by the server when the only option is to show | |
* an error page, since we do not have enough information to redirect | |
* back to the consumer. The associated value is an error message that | |
* should be displayed on an HTML error page. | |
* | |
* @see Auth_OpenID_Server | |
*/ | |
define('Auth_OpenID_LOCAL_ERROR', 'local_error'); | |
/** | |
* Status code returned when there is an error to return in key-value | |
* form to the consumer. The caller should return a 400 Bad Request | |
* response with content-type text/plain and the value as the body. | |
* | |
* @see Auth_OpenID_Server | |
*/ | |
define('Auth_OpenID_REMOTE_ERROR', 'remote_error'); | |
/** | |
* Status code returned when there is a key-value form OK response to | |
* the consumer. The value associated with this code is the | |
* response. The caller should return a 200 OK response with | |
* content-type text/plain and the value as the body. | |
* | |
* @see Auth_OpenID_Server | |
*/ | |
define('Auth_OpenID_REMOTE_OK', 'remote_ok'); | |
/** | |
* Status code returned when there is a redirect back to the | |
* consumer. The value is the URL to redirect back to. The caller | |
* should return a 302 Found redirect with a Location: header | |
* containing the URL. | |
* | |
* @see Auth_OpenID_Server | |
*/ | |
define('Auth_OpenID_REDIRECT', 'redirect'); | |
/** | |
* Status code returned when the caller needs to authenticate the | |
* user. The associated value is a {@link Auth_OpenID_ServerRequest} | |
* object that can be used to complete the authentication. If the user | |
* has taken some authentication action, use the retry() method of the | |
* {@link Auth_OpenID_ServerRequest} object to complete the request. | |
* | |
* @see Auth_OpenID_Server | |
*/ | |
define('Auth_OpenID_DO_AUTH', 'do_auth'); | |
/** | |
* Status code returned when there were no OpenID arguments | |
* passed. This code indicates that the caller should return a 200 OK | |
* response and display an HTML page that says that this is an OpenID | |
* server endpoint. | |
* | |
* @see Auth_OpenID_Server | |
*/ | |
define('Auth_OpenID_DO_ABOUT', 'do_about'); | |
/** | |
* Defines for regexes and format checking. | |
*/ | |
define('Auth_OpenID_letters', | |
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); | |
define('Auth_OpenID_digits', | |
"0123456789"); | |
define('Auth_OpenID_punct', | |
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"); | |
Auth_OpenID_include_init(); | |
/** | |
* The OpenID utility function class. | |
* | |
* @package OpenID | |
* @access private | |
*/ | |
class Auth_OpenID { | |
/** | |
* Return true if $thing is an Auth_OpenID_FailureResponse object; | |
* false if not. | |
* | |
* @access private | |
*/ | |
static function isFailure($thing) | |
{ | |
return is_a($thing, 'Auth_OpenID_FailureResponse'); | |
} | |
/** | |
* Gets the query data from the server environment based on the | |
* request method used. If GET was used, this looks at | |
* $_SERVER['QUERY_STRING'] directly. If POST was used, this | |
* fetches data from the special php://input file stream. | |
* | |
* Returns an associative array of the query arguments. | |
* | |
* Skips invalid key/value pairs (i.e. keys with no '=value' | |
* portion). | |
* | |
* Returns an empty array if neither GET nor POST was used, or if | |
* POST was used but php://input cannot be opened. | |
* | |
* See background: | |
* http://lists.openidenabled.com/pipermail/dev/2007-March/000395.html | |
* | |
* @access private | |
*/ | |
static function getQuery($query_str=null) | |
{ | |
$data = array(); | |
if ($query_str !== null) { | |
$data = Auth_OpenID::params_from_string($query_str); | |
} else if (!array_key_exists('REQUEST_METHOD', $_SERVER)) { | |
// Do nothing. | |
} else { | |
// XXX HACK FIXME HORRIBLE. | |
// | |
// POSTing to a URL with query parameters is acceptable, but | |
// we don't have a clean way to distinguish those parameters | |
// when we need to do things like return_to verification | |
// which only want to look at one kind of parameter. We're | |
// going to emulate the behavior of some other environments | |
// by defaulting to GET and overwriting with POST if POST | |
// data is available. | |
$data = Auth_OpenID::params_from_string($_SERVER['QUERY_STRING']); | |
if ($_SERVER['REQUEST_METHOD'] == 'POST') { | |
$str = file_get_contents('php://input'); | |
if ($str === false) { | |
$post = array(); | |
} else { | |
$post = Auth_OpenID::params_from_string($str); | |
} | |
$data = array_merge($data, $post); | |
} | |
} | |
return $data; | |
} | |
static function params_from_string($str) | |
{ | |
$chunks = explode("&", $str); | |
$data = array(); | |
foreach ($chunks as $chunk) { | |
$parts = explode("=", $chunk, 2); | |
if (count($parts) != 2) { | |
continue; | |
} | |
list($k, $v) = $parts; | |
$data[urldecode($k)] = urldecode($v); | |
} | |
return $data; | |
} | |
/** | |
* Create dir_name as a directory if it does not exist. If it | |
* exists, make sure that it is, in fact, a directory. Returns | |
* true if the operation succeeded; false if not. | |
* | |
* @access private | |
*/ | |
static function ensureDir($dir_name) | |
{ | |
if (is_dir($dir_name) || @mkdir($dir_name)) { | |
return true; | |
} else { | |
$parent_dir = dirname($dir_name); | |
// Terminal case; there is no parent directory to create. | |
if ($parent_dir == $dir_name) { | |
return true; | |
} | |
return (Auth_OpenID::ensureDir($parent_dir) && @mkdir($dir_name)); | |
} | |
} | |
/** | |
* Adds a string prefix to all values of an array. Returns a new | |
* array containing the prefixed values. | |
* | |
* @access private | |
*/ | |
static function addPrefix($values, $prefix) | |
{ | |
$new_values = array(); | |
foreach ($values as $s) { | |
$new_values[] = $prefix . $s; | |
} | |
return $new_values; | |
} | |
/** | |
* Convenience function for getting array values. Given an array | |
* $arr and a key $key, get the corresponding value from the array | |
* or return $default if the key is absent. | |
* | |
* @access private | |
*/ | |
static function arrayGet($arr, $key, $fallback = null) | |
{ | |
if (is_array($arr)) { | |
if (array_key_exists($key, $arr)) { | |
return $arr[$key]; | |
} else { | |
return $fallback; | |
} | |
} else { | |
trigger_error("Auth_OpenID::arrayGet (key = ".$key.") expected " . | |
"array as first parameter, got " . | |
gettype($arr), E_USER_WARNING); | |
return false; | |
} | |
} | |
/** | |
* Replacement for PHP's broken parse_str. | |
*/ | |
static function parse_str($query) | |
{ | |
if ($query === null) { | |
return null; | |
} | |
$parts = explode('&', $query); | |
$new_parts = array(); | |
for ($i = 0; $i < count($parts); $i++) { | |
$pair = explode('=', $parts[$i]); | |
if (count($pair) != 2) { | |
continue; | |
} | |
list($key, $value) = $pair; | |
$new_parts[urldecode($key)] = urldecode($value); | |
} | |
return $new_parts; | |
} | |
/** | |
* Implements the PHP 5 'http_build_query' functionality. | |
* | |
* @access private | |
* @param array $data Either an array key/value pairs or an array | |
* of arrays, each of which holding two values: a key and a value, | |
* sequentially. | |
* @return string $result The result of url-encoding the key/value | |
* pairs from $data into a URL query string | |
* (e.g. "username=bob&id=56"). | |
*/ | |
static function httpBuildQuery($data) | |
{ | |
$pairs = array(); | |
foreach ($data as $key => $value) { | |
if (is_array($value)) { | |
$pairs[] = urlencode($value[0])."=".urlencode($value[1]); | |
} else { | |
$pairs[] = urlencode($key)."=".urlencode($value); | |
} | |
} | |
return implode("&", $pairs); | |
} | |
/** | |
* "Appends" query arguments onto a URL. The URL may or may not | |
* already have arguments (following a question mark). | |
* | |
* @access private | |
* @param string $url A URL, which may or may not already have | |
* arguments. | |
* @param array $args Either an array key/value pairs or an array of | |
* arrays, each of which holding two values: a key and a value, | |
* sequentially. If $args is an ordinary key/value array, the | |
* parameters will be added to the URL in sorted alphabetical order; | |
* if $args is an array of arrays, their order will be preserved. | |
* @return string $url The original URL with the new parameters added. | |
* | |
*/ | |
static function appendArgs($url, $args) | |
{ | |
if (count($args) == 0) { | |
return $url; | |
} | |
// Non-empty array; if it is an array of arrays, use | |
// multisort; otherwise use sort. | |
if (array_key_exists(0, $args) && | |
is_array($args[0])) { | |
// Do nothing here. | |
} else { | |
$keys = array_keys($args); | |
sort($keys); | |
$new_args = array(); | |
foreach ($keys as $key) { | |
$new_args[] = array($key, $args[$key]); | |
} | |
$args = $new_args; | |
} | |
$sep = '?'; | |
if (strpos($url, '?') !== false) { | |
$sep = '&'; | |
} | |
return $url . $sep . Auth_OpenID::httpBuildQuery($args); | |
} | |
/** | |
* Implements python's urlunparse, which is not available in PHP. | |
* Given the specified components of a URL, this function rebuilds | |
* and returns the URL. | |
* | |
* @access private | |
* @param string $scheme The scheme (e.g. 'http'). Defaults to 'http'. | |
* @param string $host The host. Required. | |
* @param string $port The port. | |
* @param string $path The path. | |
* @param string $query The query. | |
* @param string $fragment The fragment. | |
* @return string $url The URL resulting from assembling the | |
* specified components. | |
*/ | |
static function urlunparse($scheme, $host, $port = null, $path = '/', | |
$query = '', $fragment = '') | |
{ | |
if (!$scheme) { | |
$scheme = 'http'; | |
} | |
if (!$host) { | |
return false; | |
} | |
if (!$path) { | |
$path = ''; | |
} | |
$result = $scheme . "://" . $host; | |
if ($port) { | |
$result .= ":" . $port; | |
} | |
$result .= $path; | |
if ($query) { | |
$result .= "?" . $query; | |
} | |
if ($fragment) { | |
$result .= "#" . $fragment; | |
} | |
return $result; | |
} | |
/** | |
* Given a URL, this "normalizes" it by adding a trailing slash | |
* and / or a leading http:// scheme where necessary. Returns | |
* null if the original URL is malformed and cannot be normalized. | |
* | |
* @access private | |
* @param string $url The URL to be normalized. | |
* @return mixed $new_url The URL after normalization, or null if | |
* $url was malformed. | |
*/ | |
static function normalizeUrl($url) | |
{ | |
@$parsed = parse_url($url); | |
if (!$parsed) { | |
return null; | |
} | |
if (isset($parsed['scheme']) && | |
isset($parsed['host'])) { | |
$scheme = strtolower($parsed['scheme']); | |
if (!in_array($scheme, array('http', 'https'))) { | |
return null; | |
} | |
} else { | |
$url = 'http://' . $url; | |
} | |
$normalized = Auth_OpenID_urinorm($url); | |
if ($normalized === null) { | |
return null; | |
} | |
list($defragged, $frag) = Auth_OpenID::urldefrag($normalized); | |
return $defragged; | |
} | |
/** | |
* Replacement (wrapper) for PHP's intval() because it's broken. | |
* | |
* @access private | |
*/ | |
static function intval($value) | |
{ | |
$re = "/^\\d+$/"; | |
if (!preg_match($re, $value)) { | |
return false; | |
} | |
return intval($value); | |
} | |
/** | |
* Count the number of bytes in a string independently of | |
* multibyte support conditions. | |
* | |
* @param string $str The string of bytes to count. | |
* @return int The number of bytes in $str. | |
*/ | |
static function bytes($str) | |
{ | |
return strlen(bin2hex($str)) / 2; | |
} | |
/** | |
* Get the bytes in a string independently of multibyte support | |
* conditions. | |
*/ | |
static function toBytes($str) | |
{ | |
$hex = bin2hex($str); | |
if (!$hex) { | |
return array(); | |
} | |
$b = array(); | |
for ($i = 0; $i < strlen($hex); $i += 2) { | |
$b[] = chr(base_convert(substr($hex, $i, 2), 16, 10)); | |
} | |
return $b; | |
} | |
static function urldefrag($url) | |
{ | |
$parts = explode("#", $url, 2); | |
if (count($parts) == 1) { | |
return array($parts[0], ""); | |
} else { | |
return $parts; | |
} | |
} | |
static function filter($callback, &$sequence) | |
{ | |
$result = array(); | |
foreach ($sequence as $item) { | |
if (call_user_func_array($callback, array($item))) { | |
$result[] = $item; | |
} | |
} | |
return $result; | |
} | |
static function update(&$dest, &$src) | |
{ | |
foreach ($src as $k => $v) { | |
$dest[$k] = $v; | |
} | |
} | |
/** | |
* Wrap PHP's standard error_log functionality. Use this to | |
* perform all logging. It will interpolate any additional | |
* arguments into the format string before logging. | |
* | |
* @param string $format_string The sprintf format for the message | |
*/ | |
static function log($format_string) | |
{ | |
$args = func_get_args(); | |
$message = call_user_func_array('sprintf', $args); | |
error_log($message); | |
} | |
static function autoSubmitHTML($form, $title="OpenId transaction in progress") | |
{ | |
return("<html>". | |
"<head><title>". | |
$title . | |
"</title></head>". | |
"<body onload='document.forms[0].submit();'>". | |
$form . | |
"<script>". | |
"var elements = document.forms[0].elements;". | |
"for (var i = 0; i < elements.length; i++) {". | |
" elements[i].style.display = \"none\";". | |
"}". | |
"</script>". | |
"</body>". | |
"</html>"); | |
} | |
} | |
/* | |
* Function to run when this file is included. | |
* Abstracted to a function to make life easier | |
* for some PHP optimizers. | |
*/ | |
function Auth_OpenID_include_init() { | |
if (Auth_OpenID_getMathLib() === null) { | |
Auth_OpenID_setNoMathSupport(); | |
} | |
} | |
<?php | |
/** | |
* Implements the OpenID attribute exchange specification, version 1.0 | |
* as of svn revision 370 from openid.net svn. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Require utility classes and functions for the consumer. | |
*/ | |
require_once "Auth/OpenID/Extension.php"; | |
require_once "Auth/OpenID/Message.php"; | |
require_once "Auth/OpenID/TrustRoot.php"; | |
define('Auth_OpenID_AX_NS_URI', | |
'http://openid.net/srv/ax/1.0'); | |
// Use this as the 'count' value for an attribute in a FetchRequest to | |
// ask for as many values as the OP can provide. | |
define('Auth_OpenID_AX_UNLIMITED_VALUES', 'unlimited'); | |
// Minimum supported alias length in characters. Here for | |
// completeness. | |
define('Auth_OpenID_AX_MINIMUM_SUPPORTED_ALIAS_LENGTH', 32); | |
/** | |
* AX utility class. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX { | |
/** | |
* @param mixed $thing Any object which may be an | |
* Auth_OpenID_AX_Error object. | |
* | |
* @return bool true if $thing is an Auth_OpenID_AX_Error; false | |
* if not. | |
*/ | |
static function isError($thing) | |
{ | |
return is_a($thing, 'Auth_OpenID_AX_Error'); | |
} | |
} | |
/** | |
* Check an alias for invalid characters; raise AXError if any are | |
* found. Return None if the alias is valid. | |
*/ | |
function Auth_OpenID_AX_checkAlias($alias) | |
{ | |
if (strpos($alias, ',') !== false) { | |
return new Auth_OpenID_AX_Error(sprintf( | |
"Alias %s must not contain comma", $alias)); | |
} | |
if (strpos($alias, '.') !== false) { | |
return new Auth_OpenID_AX_Error(sprintf( | |
"Alias %s must not contain period", $alias)); | |
} | |
return true; | |
} | |
/** | |
* Results from data that does not meet the attribute exchange 1.0 | |
* specification | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_Error { | |
function Auth_OpenID_AX_Error($message=null) | |
{ | |
$this->message = $message; | |
} | |
} | |
/** | |
* Abstract class containing common code for attribute exchange | |
* messages. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_Message extends Auth_OpenID_Extension { | |
/** | |
* ns_alias: The preferred namespace alias for attribute exchange | |
* messages | |
*/ | |
var $ns_alias = 'ax'; | |
/** | |
* mode: The type of this attribute exchange message. This must be | |
* overridden in subclasses. | |
*/ | |
var $mode = null; | |
var $ns_uri = Auth_OpenID_AX_NS_URI; | |
/** | |
* Return Auth_OpenID_AX_Error if the mode in the attribute | |
* exchange arguments does not match what is expected for this | |
* class; true otherwise. | |
* | |
* @access private | |
*/ | |
function _checkMode($ax_args) | |
{ | |
$mode = Auth_OpenID::arrayGet($ax_args, 'mode'); | |
if ($mode != $this->mode) { | |
return new Auth_OpenID_AX_Error( | |
sprintf( | |
"Expected mode '%s'; got '%s'", | |
$this->mode, $mode)); | |
} | |
return true; | |
} | |
/** | |
* Return a set of attribute exchange arguments containing the | |
* basic information that must be in every attribute exchange | |
* message. | |
* | |
* @access private | |
*/ | |
function _newArgs() | |
{ | |
return array('mode' => $this->mode); | |
} | |
} | |
/** | |
* Represents a single attribute in an attribute exchange | |
* request. This should be added to an AXRequest object in order to | |
* request the attribute. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_AttrInfo { | |
/** | |
* Construct an attribute information object. Do not call this | |
* directly; call make(...) instead. | |
* | |
* @param string $type_uri The type URI for this attribute. | |
* | |
* @param int $count The number of values of this type to request. | |
* | |
* @param bool $required Whether the attribute will be marked as | |
* required in the request. | |
* | |
* @param string $alias The name that should be given to this | |
* attribute in the request. | |
*/ | |
function Auth_OpenID_AX_AttrInfo($type_uri, $count, $required, | |
$alias) | |
{ | |
/** | |
* required: Whether the attribute will be marked as required | |
* when presented to the subject of the attribute exchange | |
* request. | |
*/ | |
$this->required = $required; | |
/** | |
* count: How many values of this type to request from the | |
* subject. Defaults to one. | |
*/ | |
$this->count = $count; | |
/** | |
* type_uri: The identifier that determines what the attribute | |
* represents and how it is serialized. For example, one type | |
* URI representing dates could represent a Unix timestamp in | |
* base 10 and another could represent a human-readable | |
* string. | |
*/ | |
$this->type_uri = $type_uri; | |
/** | |
* alias: The name that should be given to this attribute in | |
* the request. If it is not supplied, a generic name will be | |
* assigned. For example, if you want to call a Unix timestamp | |
* value 'tstamp', set its alias to that value. If two | |
* attributes in the same message request to use the same | |
* alias, the request will fail to be generated. | |
*/ | |
$this->alias = $alias; | |
} | |
/** | |
* Construct an attribute information object. For parameter | |
* details, see the constructor. | |
*/ | |
static function make($type_uri, $count=1, $required=false, | |
$alias=null) | |
{ | |
if ($alias !== null) { | |
$result = Auth_OpenID_AX_checkAlias($alias); | |
if (Auth_OpenID_AX::isError($result)) { | |
return $result; | |
} | |
} | |
return new Auth_OpenID_AX_AttrInfo($type_uri, $count, $required, | |
$alias); | |
} | |
/** | |
* When processing a request for this attribute, the OP should | |
* call this method to determine whether all available attribute | |
* values were requested. If self.count == UNLIMITED_VALUES, this | |
* returns True. Otherwise this returns False, in which case | |
* self.count is an integer. | |
*/ | |
function wantsUnlimitedValues() | |
{ | |
return $this->count === Auth_OpenID_AX_UNLIMITED_VALUES; | |
} | |
} | |
/** | |
* Given a namespace mapping and a string containing a comma-separated | |
* list of namespace aliases, return a list of type URIs that | |
* correspond to those aliases. | |
* | |
* @param $namespace_map The mapping from namespace URI to alias | |
* @param $alias_list_s The string containing the comma-separated | |
* list of aliases. May also be None for convenience. | |
* | |
* @return $seq The list of namespace URIs that corresponds to the | |
* supplied list of aliases. If the string was zero-length or None, an | |
* empty list will be returned. | |
* | |
* return null If an alias is present in the list of aliases but | |
* is not present in the namespace map. | |
*/ | |
function Auth_OpenID_AX_toTypeURIs($namespace_map, $alias_list_s) | |
{ | |
$uris = array(); | |
if ($alias_list_s) { | |
foreach (explode(',', $alias_list_s) as $alias) { | |
$type_uri = $namespace_map->getNamespaceURI($alias); | |
if ($type_uri === null) { | |
// raise KeyError( | |
// 'No type is defined for attribute name %r' % (alias,)) | |
return new Auth_OpenID_AX_Error( | |
sprintf('No type is defined for attribute name %s', | |
$alias) | |
); | |
} else { | |
$uris[] = $type_uri; | |
} | |
} | |
} | |
return $uris; | |
} | |
/** | |
* An attribute exchange 'fetch_request' message. This message is sent | |
* by a relying party when it wishes to obtain attributes about the | |
* subject of an OpenID authentication request. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_FetchRequest extends Auth_OpenID_AX_Message { | |
var $mode = 'fetch_request'; | |
function Auth_OpenID_AX_FetchRequest($update_url=null) | |
{ | |
/** | |
* requested_attributes: The attributes that have been | |
* requested thus far, indexed by the type URI. | |
*/ | |
$this->requested_attributes = array(); | |
/** | |
* update_url: A URL that will accept responses for this | |
* attribute exchange request, even in the absence of the user | |
* who made this request. | |
*/ | |
$this->update_url = $update_url; | |
} | |
/** | |
* Add an attribute to this attribute exchange request. | |
* | |
* @param attribute: The attribute that is being requested | |
* @return true on success, false when the requested attribute is | |
* already present in this fetch request. | |
*/ | |
function add($attribute) | |
{ | |
if ($this->contains($attribute->type_uri)) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("The attribute %s has already been requested", | |
$attribute->type_uri)); | |
} | |
$this->requested_attributes[$attribute->type_uri] = $attribute; | |
return true; | |
} | |
/** | |
* Get the serialized form of this attribute fetch request. | |
* | |
* @returns Auth_OpenID_AX_FetchRequest The fetch request message parameters | |
*/ | |
function getExtensionArgs() | |
{ | |
$aliases = new Auth_OpenID_NamespaceMap(); | |
$required = array(); | |
$if_available = array(); | |
$ax_args = $this->_newArgs(); | |
foreach ($this->requested_attributes as $type_uri => $attribute) { | |
if ($attribute->alias === null) { | |
$alias = $aliases->add($type_uri); | |
} else { | |
$alias = $aliases->addAlias($type_uri, $attribute->alias); | |
if ($alias === null) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Could not add alias %s for URI %s", | |
$attribute->alias, $type_uri | |
)); | |
} | |
} | |
if ($attribute->required) { | |
$required[] = $alias; | |
} else { | |
$if_available[] = $alias; | |
} | |
if ($attribute->count != 1) { | |
$ax_args['count.' . $alias] = strval($attribute->count); | |
} | |
$ax_args['type.' . $alias] = $type_uri; | |
} | |
if ($required) { | |
$ax_args['required'] = implode(',', $required); | |
} | |
if ($if_available) { | |
$ax_args['if_available'] = implode(',', $if_available); | |
} | |
return $ax_args; | |
} | |
/** | |
* Get the type URIs for all attributes that have been marked as | |
* required. | |
* | |
* @return A list of the type URIs for attributes that have been | |
* marked as required. | |
*/ | |
function getRequiredAttrs() | |
{ | |
$required = array(); | |
foreach ($this->requested_attributes as $type_uri => $attribute) { | |
if ($attribute->required) { | |
$required[] = $type_uri; | |
} | |
} | |
return $required; | |
} | |
/** | |
* Extract a FetchRequest from an OpenID message | |
* | |
* @param request: The OpenID request containing the attribute | |
* fetch request | |
* | |
* @returns mixed An Auth_OpenID_AX_Error or the | |
* Auth_OpenID_AX_FetchRequest extracted from the request message if | |
* successful | |
*/ | |
static function fromOpenIDRequest($request) | |
{ | |
$m = $request->message; | |
$obj = new Auth_OpenID_AX_FetchRequest(); | |
$ax_args = $m->getArgs($obj->ns_uri); | |
$result = $obj->parseExtensionArgs($ax_args); | |
if (Auth_OpenID_AX::isError($result)) { | |
return $result; | |
} | |
if ($obj->update_url) { | |
// Update URL must match the openid.realm of the | |
// underlying OpenID 2 message. | |
$realm = $m->getArg(Auth_OpenID_OPENID_NS, 'realm', | |
$m->getArg( | |
Auth_OpenID_OPENID_NS, | |
'return_to')); | |
if (!$realm) { | |
$obj = new Auth_OpenID_AX_Error( | |
sprintf("Cannot validate update_url %s " . | |
"against absent realm", $obj->update_url)); | |
} else if (!Auth_OpenID_TrustRoot::match($realm, | |
$obj->update_url)) { | |
$obj = new Auth_OpenID_AX_Error( | |
sprintf("Update URL %s failed validation against realm %s", | |
$obj->update_url, $realm)); | |
} | |
} | |
return $obj; | |
} | |
/** | |
* Given attribute exchange arguments, populate this FetchRequest. | |
* | |
* @return $result Auth_OpenID_AX_Error if the data to be parsed | |
* does not follow the attribute exchange specification. At least | |
* when 'if_available' or 'required' is not specified for a | |
* particular attribute type. Returns true otherwise. | |
*/ | |
function parseExtensionArgs($ax_args) | |
{ | |
$result = $this->_checkMode($ax_args); | |
if (Auth_OpenID_AX::isError($result)) { | |
return $result; | |
} | |
$aliases = new Auth_OpenID_NamespaceMap(); | |
foreach ($ax_args as $key => $value) { | |
if (strpos($key, 'type.') === 0) { | |
$alias = substr($key, 5); | |
$type_uri = $value; | |
$alias = $aliases->addAlias($type_uri, $alias); | |
if ($alias === null) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Could not add alias %s for URI %s", | |
$alias, $type_uri) | |
); | |
} | |
$count_s = Auth_OpenID::arrayGet($ax_args, 'count.' . $alias); | |
if ($count_s) { | |
$count = Auth_OpenID::intval($count_s); | |
if (($count === false) && | |
($count_s === Auth_OpenID_AX_UNLIMITED_VALUES)) { | |
$count = $count_s; | |
} | |
} else { | |
$count = 1; | |
} | |
if ($count === false) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Integer value expected for %s, got %s", | |
'count.' . $alias, $count_s)); | |
} | |
$attrinfo = Auth_OpenID_AX_AttrInfo::make($type_uri, $count, | |
false, $alias); | |
if (Auth_OpenID_AX::isError($attrinfo)) { | |
return $attrinfo; | |
} | |
$this->add($attrinfo); | |
} | |
} | |
$required = Auth_OpenID_AX_toTypeURIs($aliases, | |
Auth_OpenID::arrayGet($ax_args, 'required')); | |
foreach ($required as $type_uri) { | |
$attrib = $this->requested_attributes[$type_uri]; | |
$attrib->required = true; | |
} | |
$if_available = Auth_OpenID_AX_toTypeURIs($aliases, | |
Auth_OpenID::arrayGet($ax_args, 'if_available')); | |
$all_type_uris = array_merge($required, $if_available); | |
foreach ($aliases->iterNamespaceURIs() as $type_uri) { | |
if (!in_array($type_uri, $all_type_uris)) { | |
return new Auth_OpenID_AX_Error( | |
sprintf('Type URI %s was in the request but not ' . | |
'present in "required" or "if_available"', | |
$type_uri)); | |
} | |
} | |
$this->update_url = Auth_OpenID::arrayGet($ax_args, 'update_url'); | |
return true; | |
} | |
/** | |
* Iterate over the AttrInfo objects that are contained in this | |
* fetch_request. | |
*/ | |
function iterAttrs() | |
{ | |
return array_values($this->requested_attributes); | |
} | |
function iterTypes() | |
{ | |
return array_keys($this->requested_attributes); | |
} | |
/** | |
* Is the given type URI present in this fetch_request? | |
*/ | |
function contains($type_uri) | |
{ | |
return in_array($type_uri, $this->iterTypes()); | |
} | |
} | |
/** | |
* An abstract class that implements a message that has attribute keys | |
* and values. It contains the common code between fetch_response and | |
* store_request. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_KeyValueMessage extends Auth_OpenID_AX_Message { | |
function Auth_OpenID_AX_KeyValueMessage() | |
{ | |
$this->data = array(); | |
} | |
/** | |
* Add a single value for the given attribute type to the | |
* message. If there are already values specified for this type, | |
* this value will be sent in addition to the values already | |
* specified. | |
* | |
* @param type_uri: The URI for the attribute | |
* @param value: The value to add to the response to the relying | |
* party for this attribute | |
* @return null | |
*/ | |
function addValue($type_uri, $value) | |
{ | |
if (!array_key_exists($type_uri, $this->data)) { | |
$this->data[$type_uri] = array(); | |
} | |
$values =& $this->data[$type_uri]; | |
$values[] = $value; | |
} | |
/** | |
* Set the values for the given attribute type. This replaces any | |
* values that have already been set for this attribute. | |
* | |
* @param type_uri: The URI for the attribute | |
* @param values: A list of values to send for this attribute. | |
*/ | |
function setValues($type_uri, &$values) | |
{ | |
$this->data[$type_uri] =& $values; | |
} | |
/** | |
* Get the extension arguments for the key/value pairs contained | |
* in this message. | |
* | |
* @param aliases: An alias mapping. Set to None if you don't care | |
* about the aliases for this request. | |
* | |
* @access private | |
*/ | |
function _getExtensionKVArgs($aliases) | |
{ | |
if ($aliases === null) { | |
$aliases = new Auth_OpenID_NamespaceMap(); | |
} | |
$ax_args = array(); | |
foreach ($this->data as $type_uri => $values) { | |
$alias = $aliases->add($type_uri); | |
$ax_args['type.' . $alias] = $type_uri; | |
$ax_args['count.' . $alias] = strval(count($values)); | |
foreach ($values as $i => $value) { | |
$key = sprintf('value.%s.%d', $alias, $i + 1); | |
$ax_args[$key] = $value; | |
} | |
} | |
return $ax_args; | |
} | |
/** | |
* Parse attribute exchange key/value arguments into this object. | |
* | |
* @param ax_args: The attribute exchange fetch_response | |
* arguments, with namespacing removed. | |
* | |
* @return Auth_OpenID_AX_Error or true | |
*/ | |
function parseExtensionArgs($ax_args) | |
{ | |
$result = $this->_checkMode($ax_args); | |
if (Auth_OpenID_AX::isError($result)) { | |
return $result; | |
} | |
$aliases = new Auth_OpenID_NamespaceMap(); | |
foreach ($ax_args as $key => $value) { | |
if (strpos($key, 'type.') === 0) { | |
$type_uri = $value; | |
$alias = substr($key, 5); | |
$result = Auth_OpenID_AX_checkAlias($alias); | |
if (Auth_OpenID_AX::isError($result)) { | |
return $result; | |
} | |
$alias = $aliases->addAlias($type_uri, $alias); | |
if ($alias === null) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Could not add alias %s for URI %s", | |
$alias, $type_uri) | |
); | |
} | |
} | |
} | |
foreach ($aliases->iteritems() as $pair) { | |
list($type_uri, $alias) = $pair; | |
if (array_key_exists('count.' . $alias, $ax_args) && ($ax_args['count.' . $alias] !== Auth_OpenID_AX_UNLIMITED_VALUES)) { | |
$count_key = 'count.' . $alias; | |
$count_s = $ax_args[$count_key]; | |
$count = Auth_OpenID::intval($count_s); | |
if ($count === false) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Integer value expected for %s, got %s", | |
'count. %s' . $alias, $count_s, | |
Auth_OpenID_AX_UNLIMITED_VALUES) | |
); | |
} | |
$values = array(); | |
for ($i = 1; $i < $count + 1; $i++) { | |
$value_key = sprintf('value.%s.%d', $alias, $i); | |
if (!array_key_exists($value_key, $ax_args)) { | |
return new Auth_OpenID_AX_Error( | |
sprintf( | |
"No value found for key %s", | |
$value_key)); | |
} | |
$value = $ax_args[$value_key]; | |
$values[] = $value; | |
} | |
} else { | |
$key = 'value.' . $alias; | |
if (!array_key_exists($key, $ax_args)) { | |
return new Auth_OpenID_AX_Error( | |
sprintf( | |
"No value found for key %s", | |
$key)); | |
} | |
$value = $ax_args['value.' . $alias]; | |
if ($value == '') { | |
$values = array(); | |
} else { | |
$values = array($value); | |
} | |
} | |
$this->data[$type_uri] = $values; | |
} | |
return true; | |
} | |
/** | |
* Get a single value for an attribute. If no value was sent for | |
* this attribute, use the supplied default. If there is more than | |
* one value for this attribute, this method will fail. | |
* | |
* @param type_uri: The URI for the attribute | |
* @param default: The value to return if the attribute was not | |
* sent in the fetch_response. | |
* | |
* @return $value Auth_OpenID_AX_Error on failure or the value of | |
* the attribute in the fetch_response message, or the default | |
* supplied | |
*/ | |
function getSingle($type_uri, $default=null) | |
{ | |
$values = Auth_OpenID::arrayGet($this->data, $type_uri); | |
if (!$values) { | |
return $default; | |
} else if (count($values) == 1) { | |
return $values[0]; | |
} else { | |
return new Auth_OpenID_AX_Error( | |
sprintf('More than one value present for %s', | |
$type_uri) | |
); | |
} | |
} | |
/** | |
* Get the list of values for this attribute in the | |
* fetch_response. | |
* | |
* XXX: what to do if the values are not present? default | |
* parameter? this is funny because it's always supposed to return | |
* a list, so the default may break that, though it's provided by | |
* the user's code, so it might be okay. If no default is | |
* supplied, should the return be None or []? | |
* | |
* @param type_uri: The URI of the attribute | |
* | |
* @return $values The list of values for this attribute in the | |
* response. May be an empty list. If the attribute was not sent | |
* in the response, returns Auth_OpenID_AX_Error. | |
*/ | |
function get($type_uri) | |
{ | |
if (array_key_exists($type_uri, $this->data)) { | |
return $this->data[$type_uri]; | |
} else { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Type URI %s not found in response", | |
$type_uri) | |
); | |
} | |
} | |
/** | |
* Get the number of responses for a particular attribute in this | |
* fetch_response message. | |
* | |
* @param type_uri: The URI of the attribute | |
* | |
* @returns int The number of values sent for this attribute. If | |
* the attribute was not sent in the response, returns | |
* Auth_OpenID_AX_Error. | |
*/ | |
function count($type_uri) | |
{ | |
if (array_key_exists($type_uri, $this->data)) { | |
return count($this->get($type_uri)); | |
} else { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Type URI %s not found in response", | |
$type_uri) | |
); | |
} | |
} | |
} | |
/** | |
* A fetch_response attribute exchange message. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_FetchResponse extends Auth_OpenID_AX_KeyValueMessage { | |
var $mode = 'fetch_response'; | |
function Auth_OpenID_AX_FetchResponse($update_url=null) | |
{ | |
$this->Auth_OpenID_AX_KeyValueMessage(); | |
$this->update_url = $update_url; | |
} | |
/** | |
* Serialize this object into arguments in the attribute exchange | |
* namespace | |
* | |
* @return $args The dictionary of unqualified attribute exchange | |
* arguments that represent this fetch_response, or | |
* Auth_OpenID_AX_Error on error. | |
*/ | |
function getExtensionArgs($request=null) | |
{ | |
$aliases = new Auth_OpenID_NamespaceMap(); | |
$zero_value_types = array(); | |
if ($request !== null) { | |
// Validate the data in the context of the request (the | |
// same attributes should be present in each, and the | |
// counts in the response must be no more than the counts | |
// in the request) | |
foreach ($this->data as $type_uri => $unused) { | |
if (!$request->contains($type_uri)) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Response attribute not present in request: %s", | |
$type_uri) | |
); | |
} | |
} | |
foreach ($request->iterAttrs() as $attr_info) { | |
// Copy the aliases from the request so that reading | |
// the response in light of the request is easier | |
if ($attr_info->alias === null) { | |
$aliases->add($attr_info->type_uri); | |
} else { | |
$alias = $aliases->addAlias($attr_info->type_uri, | |
$attr_info->alias); | |
if ($alias === null) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("Could not add alias %s for URI %s", | |
$attr_info->alias, $attr_info->type_uri) | |
); | |
} | |
} | |
if (array_key_exists($attr_info->type_uri, $this->data)) { | |
$values = $this->data[$attr_info->type_uri]; | |
} else { | |
$values = array(); | |
$zero_value_types[] = $attr_info; | |
} | |
if (($attr_info->count != Auth_OpenID_AX_UNLIMITED_VALUES) && | |
($attr_info->count < count($values))) { | |
return new Auth_OpenID_AX_Error( | |
sprintf("More than the number of requested values " . | |
"were specified for %s", | |
$attr_info->type_uri) | |
); | |
} | |
} | |
} | |
$kv_args = $this->_getExtensionKVArgs($aliases); | |
// Add the KV args into the response with the args that are | |
// unique to the fetch_response | |
$ax_args = $this->_newArgs(); | |
// For each requested attribute, put its type/alias and count | |
// into the response even if no data were returned. | |
foreach ($zero_value_types as $attr_info) { | |
$alias = $aliases->getAlias($attr_info->type_uri); | |
$kv_args['type.' . $alias] = $attr_info->type_uri; | |
$kv_args['count.' . $alias] = '0'; | |
} | |
$update_url = null; | |
if ($request) { | |
$update_url = $request->update_url; | |
} else { | |
$update_url = $this->update_url; | |
} | |
if ($update_url) { | |
$ax_args['update_url'] = $update_url; | |
} | |
Auth_OpenID::update($ax_args, $kv_args); | |
return $ax_args; | |
} | |
/** | |
* @return $result Auth_OpenID_AX_Error on failure or true on | |
* success. | |
*/ | |
function parseExtensionArgs($ax_args) | |
{ | |
$result = parent::parseExtensionArgs($ax_args); | |
if (Auth_OpenID_AX::isError($result)) { | |
return $result; | |
} | |
$this->update_url = Auth_OpenID::arrayGet($ax_args, 'update_url'); | |
return true; | |
} | |
/** | |
* Construct a FetchResponse object from an OpenID library | |
* SuccessResponse object. | |
* | |
* @param success_response: A successful id_res response object | |
* | |
* @param signed: Whether non-signed args should be processsed. If | |
* True (the default), only signed arguments will be processsed. | |
* | |
* @return $response A FetchResponse containing the data from the | |
* OpenID message | |
*/ | |
static function fromSuccessResponse($success_response, $signed=true) | |
{ | |
$obj = new Auth_OpenID_AX_FetchResponse(); | |
if ($signed) { | |
$ax_args = $success_response->getSignedNS($obj->ns_uri); | |
} else { | |
$ax_args = $success_response->message->getArgs($obj->ns_uri); | |
} | |
if ($ax_args === null || Auth_OpenID::isFailure($ax_args) || | |
sizeof($ax_args) == 0) { | |
return null; | |
} | |
$result = $obj->parseExtensionArgs($ax_args); | |
if (Auth_OpenID_AX::isError($result)) { | |
#XXX log me | |
return null; | |
} | |
return $obj; | |
} | |
} | |
/** | |
* A store request attribute exchange message representation. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_StoreRequest extends Auth_OpenID_AX_KeyValueMessage { | |
var $mode = 'store_request'; | |
/** | |
* @param array $aliases The namespace aliases to use when making | |
* this store response. Leave as None to use defaults. | |
*/ | |
function getExtensionArgs($aliases=null) | |
{ | |
$ax_args = $this->_newArgs(); | |
$kv_args = $this->_getExtensionKVArgs($aliases); | |
Auth_OpenID::update($ax_args, $kv_args); | |
return $ax_args; | |
} | |
} | |
/** | |
* An indication that the store request was processed along with this | |
* OpenID transaction. Use make(), NOT the constructor, to create | |
* response objects. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_AX_StoreResponse extends Auth_OpenID_AX_Message { | |
var $SUCCESS_MODE = 'store_response_success'; | |
var $FAILURE_MODE = 'store_response_failure'; | |
/** | |
* Returns Auth_OpenID_AX_Error on error or an | |
* Auth_OpenID_AX_StoreResponse object on success. | |
*/ | |
function make($succeeded=true, $error_message=null) | |
{ | |
if (($succeeded) && ($error_message !== null)) { | |
return new Auth_OpenID_AX_Error('An error message may only be '. | |
'included in a failing fetch response'); | |
} | |
return new Auth_OpenID_AX_StoreResponse($succeeded, $error_message); | |
} | |
function Auth_OpenID_AX_StoreResponse($succeeded=true, $error_message=null) | |
{ | |
if ($succeeded) { | |
$this->mode = $this->SUCCESS_MODE; | |
} else { | |
$this->mode = $this->FAILURE_MODE; | |
} | |
$this->error_message = $error_message; | |
} | |
/** | |
* Was this response a success response? | |
*/ | |
function succeeded() | |
{ | |
return $this->mode == $this->SUCCESS_MODE; | |
} | |
function getExtensionArgs() | |
{ | |
$ax_args = $this->_newArgs(); | |
if ((!$this->succeeded()) && $this->error_message) { | |
$ax_args['error'] = $this->error_message; | |
} | |
return $ax_args; | |
} | |
} | |
<?php | |
/** | |
* This module contains code for dealing with associations between | |
* consumers and servers. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/CryptUtil.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/KVForm.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/HMAC.php'; | |
/** | |
* This class represents an association between a server and a | |
* consumer. In general, users of this library will never see | |
* instances of this object. The only exception is if you implement a | |
* custom {@link Auth_OpenID_OpenIDStore}. | |
* | |
* If you do implement such a store, it will need to store the values | |
* of the handle, secret, issued, lifetime, and assoc_type instance | |
* variables. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_Association { | |
/** | |
* This is a HMAC-SHA1 specific value. | |
* | |
* @access private | |
*/ | |
var $SIG_LENGTH = 20; | |
/** | |
* The ordering and name of keys as stored by serialize. | |
* | |
* @access private | |
*/ | |
var $assoc_keys = array( | |
'version', | |
'handle', | |
'secret', | |
'issued', | |
'lifetime', | |
'assoc_type' | |
); | |
var $_macs = array( | |
'HMAC-SHA1' => 'Auth_OpenID_HMACSHA1', | |
'HMAC-SHA256' => 'Auth_OpenID_HMACSHA256' | |
); | |
/** | |
* This is an alternate constructor (factory method) used by the | |
* OpenID consumer library to create associations. OpenID store | |
* implementations shouldn't use this constructor. | |
* | |
* @access private | |
* | |
* @param integer $expires_in This is the amount of time this | |
* association is good for, measured in seconds since the | |
* association was issued. | |
* | |
* @param string $handle This is the handle the server gave this | |
* association. | |
* | |
* @param string secret This is the shared secret the server | |
* generated for this association. | |
* | |
* @param assoc_type This is the type of association this | |
* instance represents. The only valid values of this field at | |
* this time is 'HMAC-SHA1' and 'HMAC-SHA256', but new types may | |
* be defined in the future. | |
* | |
* @return association An {@link Auth_OpenID_Association} | |
* instance. | |
*/ | |
static function fromExpiresIn($expires_in, $handle, $secret, $assoc_type) | |
{ | |
$issued = time(); | |
$lifetime = $expires_in; | |
return new Auth_OpenID_Association($handle, $secret, | |
$issued, $lifetime, $assoc_type); | |
} | |
/** | |
* This is the standard constructor for creating an association. | |
* The library should create all of the necessary associations, so | |
* this constructor is not part of the external API. | |
* | |
* @access private | |
* | |
* @param string $handle This is the handle the server gave this | |
* association. | |
* | |
* @param string $secret This is the shared secret the server | |
* generated for this association. | |
* | |
* @param integer $issued This is the time this association was | |
* issued, in seconds since 00:00 GMT, January 1, 1970. (ie, a | |
* unix timestamp) | |
* | |
* @param integer $lifetime This is the amount of time this | |
* association is good for, measured in seconds since the | |
* association was issued. | |
* | |
* @param string $assoc_type This is the type of association this | |
* instance represents. The only valid values of this field at | |
* this time is 'HMAC-SHA1' and 'HMAC-SHA256', but new types may | |
* be defined in the future. | |
*/ | |
function Auth_OpenID_Association( | |
$handle, $secret, $issued, $lifetime, $assoc_type) | |
{ | |
if (!in_array($assoc_type, | |
Auth_OpenID_getSupportedAssociationTypes(), true)) { | |
$fmt = 'Unsupported association type (%s)'; | |
trigger_error(sprintf($fmt, $assoc_type), E_USER_ERROR); | |
} | |
$this->handle = $handle; | |
$this->secret = $secret; | |
$this->issued = $issued; | |
$this->lifetime = $lifetime; | |
$this->assoc_type = $assoc_type; | |
} | |
/** | |
* This returns the number of seconds this association is still | |
* valid for, or 0 if the association is no longer valid. | |
* | |
* @return integer $seconds The number of seconds this association | |
* is still valid for, or 0 if the association is no longer valid. | |
*/ | |
function getExpiresIn($now = null) | |
{ | |
if ($now == null) { | |
$now = time(); | |
} | |
return max(0, $this->issued + $this->lifetime - $now); | |
} | |
/** | |
* This checks to see if two {@link Auth_OpenID_Association} | |
* instances represent the same association. | |
* | |
* @return bool $result true if the two instances represent the | |
* same association, false otherwise. | |
*/ | |
function equal($other) | |
{ | |
return ((gettype($this) == gettype($other)) | |
&& ($this->handle == $other->handle) | |
&& ($this->secret == $other->secret) | |
&& ($this->issued == $other->issued) | |
&& ($this->lifetime == $other->lifetime) | |
&& ($this->assoc_type == $other->assoc_type)); | |
} | |
/** | |
* Convert an association to KV form. | |
* | |
* @return string $result String in KV form suitable for | |
* deserialization by deserialize. | |
*/ | |
function serialize() | |
{ | |
$data = array( | |
'version' => '2', | |
'handle' => $this->handle, | |
'secret' => base64_encode($this->secret), | |
'issued' => strval(intval($this->issued)), | |
'lifetime' => strval(intval($this->lifetime)), | |
'assoc_type' => $this->assoc_type | |
); | |
assert(array_keys($data) == $this->assoc_keys); | |
return Auth_OpenID_KVForm::fromArray($data, $strict = true); | |
} | |
/** | |
* Parse an association as stored by serialize(). This is the | |
* inverse of serialize. | |
* | |
* @param string $assoc_s Association as serialized by serialize() | |
* @return Auth_OpenID_Association $result instance of this class | |
*/ | |
static function deserialize($class_name, $assoc_s) | |
{ | |
$pairs = Auth_OpenID_KVForm::toArray($assoc_s, $strict = true); | |
$keys = array(); | |
$values = array(); | |
foreach ($pairs as $key => $value) { | |
if (is_array($value)) { | |
list($key, $value) = $value; | |
} | |
$keys[] = $key; | |
$values[] = $value; | |
} | |
$class_vars = get_class_vars($class_name); | |
$class_assoc_keys = $class_vars['assoc_keys']; | |
sort($keys); | |
sort($class_assoc_keys); | |
if ($keys != $class_assoc_keys) { | |
trigger_error('Unexpected key values: ' . var_export($keys, true), | |
E_USER_WARNING); | |
return null; | |
} | |
$version = $pairs['version']; | |
$handle = $pairs['handle']; | |
$secret = $pairs['secret']; | |
$issued = $pairs['issued']; | |
$lifetime = $pairs['lifetime']; | |
$assoc_type = $pairs['assoc_type']; | |
if ($version != '2') { | |
trigger_error('Unknown version: ' . $version, E_USER_WARNING); | |
return null; | |
} | |
$issued = intval($issued); | |
$lifetime = intval($lifetime); | |
$secret = base64_decode($secret); | |
return new $class_name( | |
$handle, $secret, $issued, $lifetime, $assoc_type); | |
} | |
/** | |
* Generate a signature for a sequence of (key, value) pairs | |
* | |
* @access private | |
* @param array $pairs The pairs to sign, in order. This is an | |
* array of two-tuples. | |
* @return string $signature The binary signature of this sequence | |
* of pairs | |
*/ | |
function sign($pairs) | |
{ | |
$kv = Auth_OpenID_KVForm::fromArray($pairs); | |
/* Invalid association types should be caught at constructor */ | |
$callback = $this->_macs[$this->assoc_type]; | |
return call_user_func_array($callback, array($this->secret, $kv)); | |
} | |
/** | |
* Generate a signature for some fields in a dictionary | |
* | |
* @access private | |
* @param array $fields The fields to sign, in order; this is an | |
* array of strings. | |
* @param array $data Dictionary of values to sign (an array of | |
* string => string pairs). | |
* @return string $signature The signature, base64 encoded | |
*/ | |
function signMessage($message) | |
{ | |
if ($message->hasKey(Auth_OpenID_OPENID_NS, 'sig') || | |
$message->hasKey(Auth_OpenID_OPENID_NS, 'signed')) { | |
// Already has a sig | |
return null; | |
} | |
$extant_handle = $message->getArg(Auth_OpenID_OPENID_NS, | |
'assoc_handle'); | |
if ($extant_handle && ($extant_handle != $this->handle)) { | |
// raise ValueError("Message has a different association handle") | |
return null; | |
} | |
$signed_message = $message; | |
$signed_message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle', | |
$this->handle); | |
$message_keys = array_keys($signed_message->toPostArgs()); | |
$signed_list = array(); | |
$signed_prefix = 'openid.'; | |
foreach ($message_keys as $k) { | |
if (strpos($k, $signed_prefix) === 0) { | |
$signed_list[] = substr($k, strlen($signed_prefix)); | |
} | |
} | |
$signed_list[] = 'signed'; | |
sort($signed_list); | |
$signed_message->setArg(Auth_OpenID_OPENID_NS, 'signed', | |
implode(',', $signed_list)); | |
$sig = $this->getMessageSignature($signed_message); | |
$signed_message->setArg(Auth_OpenID_OPENID_NS, 'sig', $sig); | |
return $signed_message; | |
} | |
/** | |
* Given a {@link Auth_OpenID_Message}, return the key/value pairs | |
* to be signed according to the signed list in the message. If | |
* the message lacks a signed list, return null. | |
* | |
* @access private | |
*/ | |
function _makePairs($message) | |
{ | |
$signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed'); | |
if (!$signed || Auth_OpenID::isFailure($signed)) { | |
// raise ValueError('Message has no signed list: %s' % (message,)) | |
return null; | |
} | |
$signed_list = explode(',', $signed); | |
$pairs = array(); | |
$data = $message->toPostArgs(); | |
foreach ($signed_list as $field) { | |
$pairs[] = array($field, Auth_OpenID::arrayGet($data, | |
'openid.' . | |
$field, '')); | |
} | |
return $pairs; | |
} | |
/** | |
* Given an {@link Auth_OpenID_Message}, return the signature for | |
* the signed list in the message. | |
* | |
* @access private | |
*/ | |
function getMessageSignature($message) | |
{ | |
$pairs = $this->_makePairs($message); | |
return base64_encode($this->sign($pairs)); | |
} | |
/** | |
* Confirm that the signature of these fields matches the | |
* signature contained in the data. | |
* | |
* @access private | |
*/ | |
function checkMessageSignature($message) | |
{ | |
$sig = $message->getArg(Auth_OpenID_OPENID_NS, | |
'sig'); | |
if (!$sig || Auth_OpenID::isFailure($sig)) { | |
return false; | |
} | |
$calculated_sig = $this->getMessageSignature($message); | |
return Auth_OpenID_CryptUtil::constEq($calculated_sig, $sig); | |
} | |
} | |
function Auth_OpenID_getSecretSize($assoc_type) | |
{ | |
if ($assoc_type == 'HMAC-SHA1') { | |
return 20; | |
} else if ($assoc_type == 'HMAC-SHA256') { | |
return 32; | |
} else { | |
return null; | |
} | |
} | |
function Auth_OpenID_getAllAssociationTypes() | |
{ | |
return array('HMAC-SHA1', 'HMAC-SHA256'); | |
} | |
function Auth_OpenID_getSupportedAssociationTypes() | |
{ | |
$a = array('HMAC-SHA1'); | |
if (Auth_OpenID_HMACSHA256_SUPPORTED) { | |
$a[] = 'HMAC-SHA256'; | |
} | |
return $a; | |
} | |
function Auth_OpenID_getSessionTypes($assoc_type) | |
{ | |
$assoc_to_session = array( | |
'HMAC-SHA1' => array('DH-SHA1', 'no-encryption')); | |
if (Auth_OpenID_HMACSHA256_SUPPORTED) { | |
$assoc_to_session['HMAC-SHA256'] = | |
array('DH-SHA256', 'no-encryption'); | |
} | |
return Auth_OpenID::arrayGet($assoc_to_session, $assoc_type, array()); | |
} | |
function Auth_OpenID_checkSessionType($assoc_type, $session_type) | |
{ | |
if (!in_array($session_type, | |
Auth_OpenID_getSessionTypes($assoc_type))) { | |
return false; | |
} | |
return true; | |
} | |
function Auth_OpenID_getDefaultAssociationOrder() | |
{ | |
$order = array(); | |
if (!Auth_OpenID_noMathSupport()) { | |
$order[] = array('HMAC-SHA1', 'DH-SHA1'); | |
if (Auth_OpenID_HMACSHA256_SUPPORTED) { | |
$order[] = array('HMAC-SHA256', 'DH-SHA256'); | |
} | |
} | |
$order[] = array('HMAC-SHA1', 'no-encryption'); | |
if (Auth_OpenID_HMACSHA256_SUPPORTED) { | |
$order[] = array('HMAC-SHA256', 'no-encryption'); | |
} | |
return $order; | |
} | |
function Auth_OpenID_getOnlyEncryptedOrder() | |
{ | |
$result = array(); | |
foreach (Auth_OpenID_getDefaultAssociationOrder() as $pair) { | |
list($assoc, $session) = $pair; | |
if ($session != 'no-encryption') { | |
if (Auth_OpenID_HMACSHA256_SUPPORTED && | |
($assoc == 'HMAC-SHA256')) { | |
$result[] = $pair; | |
} else if ($assoc != 'HMAC-SHA256') { | |
$result[] = $pair; | |
} | |
} | |
} | |
return $result; | |
} | |
function Auth_OpenID_getDefaultNegotiator() | |
{ | |
return new Auth_OpenID_SessionNegotiator( | |
Auth_OpenID_getDefaultAssociationOrder()); | |
} | |
function Auth_OpenID_getEncryptedNegotiator() | |
{ | |
return new Auth_OpenID_SessionNegotiator( | |
Auth_OpenID_getOnlyEncryptedOrder()); | |
} | |
/** | |
* A session negotiator controls the allowed and preferred association | |
* types and association session types. Both the {@link | |
* Auth_OpenID_Consumer} and {@link Auth_OpenID_Server} use | |
* negotiators when creating associations. | |
* | |
* You can create and use negotiators if you: | |
* - Do not want to do Diffie-Hellman key exchange because you use | |
* transport-layer encryption (e.g. SSL) | |
* | |
* - Want to use only SHA-256 associations | |
* | |
* - Do not want to support plain-text associations over a non-secure | |
* channel | |
* | |
* It is up to you to set a policy for what kinds of associations to | |
* accept. By default, the library will make any kind of association | |
* that is allowed in the OpenID 2.0 specification. | |
* | |
* Use of negotiators in the library | |
* ================================= | |
* | |
* When a consumer makes an association request, it calls {@link | |
* getAllowedType} to get the preferred association type and | |
* association session type. | |
* | |
* The server gets a request for a particular association/session type | |
* and calls {@link isAllowed} to determine if it should create an | |
* association. If it is supported, negotiation is complete. If it is | |
* not, the server calls {@link getAllowedType} to get an allowed | |
* association type to return to the consumer. | |
* | |
* If the consumer gets an error response indicating that the | |
* requested association/session type is not supported by the server | |
* that contains an assocation/session type to try, it calls {@link | |
* isAllowed} to determine if it should try again with the given | |
* combination of association/session type. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_SessionNegotiator { | |
function Auth_OpenID_SessionNegotiator($allowed_types) | |
{ | |
$this->allowed_types = array(); | |
$this->setAllowedTypes($allowed_types); | |
} | |
/** | |
* Set the allowed association types, checking to make sure each | |
* combination is valid. | |
* | |
* @access private | |
*/ | |
function setAllowedTypes($allowed_types) | |
{ | |
foreach ($allowed_types as $pair) { | |
list($assoc_type, $session_type) = $pair; | |
if (!Auth_OpenID_checkSessionType($assoc_type, $session_type)) { | |
return false; | |
} | |
} | |
$this->allowed_types = $allowed_types; | |
return true; | |
} | |
/** | |
* Add an association type and session type to the allowed types | |
* list. The assocation/session pairs are tried in the order that | |
* they are added. | |
* | |
* @access private | |
*/ | |
function addAllowedType($assoc_type, $session_type = null) | |
{ | |
if ($this->allowed_types === null) { | |
$this->allowed_types = array(); | |
} | |
if ($session_type === null) { | |
$available = Auth_OpenID_getSessionTypes($assoc_type); | |
if (!$available) { | |
return false; | |
} | |
foreach ($available as $session_type) { | |
$this->addAllowedType($assoc_type, $session_type); | |
} | |
} else { | |
if (Auth_OpenID_checkSessionType($assoc_type, $session_type)) { | |
$this->allowed_types[] = array($assoc_type, $session_type); | |
} else { | |
return false; | |
} | |
} | |
return true; | |
} | |
// Is this combination of association type and session type allowed? | |
function isAllowed($assoc_type, $session_type) | |
{ | |
$assoc_good = in_array(array($assoc_type, $session_type), | |
$this->allowed_types); | |
$matches = in_array($session_type, | |
Auth_OpenID_getSessionTypes($assoc_type)); | |
return ($assoc_good && $matches); | |
} | |
/** | |
* Get a pair of assocation type and session type that are | |
* supported. | |
*/ | |
function getAllowedType() | |
{ | |
if (!$this->allowed_types) { | |
return array(null, null); | |
} | |
return $this->allowed_types[0]; | |
} | |
} | |
<?php | |
/** | |
* BigMath: A math library wrapper that abstracts out the underlying | |
* long integer library. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @access private | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Needed for random number generation | |
*/ | |
require_once 'Auth/OpenID/CryptUtil.php'; | |
/** | |
* Need Auth_OpenID::bytes(). | |
*/ | |
require_once 'Auth/OpenID.php'; | |
/** | |
* The superclass of all big-integer math implementations | |
* @access private | |
* @package OpenID | |
*/ | |
class Auth_OpenID_MathLibrary { | |
/** | |
* Given a long integer, returns the number converted to a binary | |
* string. This function accepts long integer values of arbitrary | |
* magnitude and uses the local large-number math library when | |
* available. | |
* | |
* @param integer $long The long number (can be a normal PHP | |
* integer or a number created by one of the available long number | |
* libraries) | |
* @return string $binary The binary version of $long | |
*/ | |
function longToBinary($long) | |
{ | |
$cmp = $this->cmp($long, 0); | |
if ($cmp < 0) { | |
$msg = __FUNCTION__ . " takes only positive integers."; | |
trigger_error($msg, E_USER_ERROR); | |
return null; | |
} | |
if ($cmp == 0) { | |
return "\x00"; | |
} | |
$bytes = array(); | |
while ($this->cmp($long, 0) > 0) { | |
array_unshift($bytes, $this->mod($long, 256)); | |
$long = $this->div($long, pow(2, 8)); | |
} | |
if ($bytes && ($bytes[0] > 127)) { | |
array_unshift($bytes, 0); | |
} | |
$string = ''; | |
foreach ($bytes as $byte) { | |
$string .= pack('C', $byte); | |
} | |
return $string; | |
} | |
/** | |
* Given a binary string, returns the binary string converted to a | |
* long number. | |
* | |
* @param string $binary The binary version of a long number, | |
* probably as a result of calling longToBinary | |
* @return integer $long The long number equivalent of the binary | |
* string $str | |
*/ | |
function binaryToLong($str) | |
{ | |
if ($str === null) { | |
return null; | |
} | |
// Use array_merge to return a zero-indexed array instead of a | |
// one-indexed array. | |
$bytes = array_merge(unpack('C*', $str)); | |
$n = $this->init(0); | |
if ($bytes && ($bytes[0] > 127)) { | |
trigger_error("bytesToNum works only for positive integers.", | |
E_USER_WARNING); | |
return null; | |
} | |
foreach ($bytes as $byte) { | |
$n = $this->mul($n, pow(2, 8)); | |
$n = $this->add($n, $byte); | |
} | |
return $n; | |
} | |
function base64ToLong($str) | |
{ | |
$b64 = base64_decode($str); | |
if ($b64 === false) { | |
return false; | |
} | |
return $this->binaryToLong($b64); | |
} | |
function longToBase64($str) | |
{ | |
return base64_encode($this->longToBinary($str)); | |
} | |
/** | |
* Returns a random number in the specified range. This function | |
* accepts $start, $stop, and $step values of arbitrary magnitude | |
* and will utilize the local large-number math library when | |
* available. | |
* | |
* @param integer $start The start of the range, or the minimum | |
* random number to return | |
* @param integer $stop The end of the range, or the maximum | |
* random number to return | |
* @param integer $step The step size, such that $result - ($step | |
* * N) = $start for some N | |
* @return integer $result The resulting randomly-generated number | |
*/ | |
function rand($stop) | |
{ | |
static $duplicate_cache = array(); | |
// Used as the key for the duplicate cache | |
$rbytes = $this->longToBinary($stop); | |
if (array_key_exists($rbytes, $duplicate_cache)) { | |
list($duplicate, $nbytes) = $duplicate_cache[$rbytes]; | |
} else { | |
if ($rbytes[0] == "\x00") { | |
$nbytes = Auth_OpenID::bytes($rbytes) - 1; | |
} else { | |
$nbytes = Auth_OpenID::bytes($rbytes); | |
} | |
$mxrand = $this->pow(256, $nbytes); | |
// If we get a number less than this, then it is in the | |
// duplicated range. | |
$duplicate = $this->mod($mxrand, $stop); | |
if (count($duplicate_cache) > 10) { | |
$duplicate_cache = array(); | |
} | |
$duplicate_cache[$rbytes] = array($duplicate, $nbytes); | |
} | |
do { | |
$bytes = "\x00" . Auth_OpenID_CryptUtil::getBytes($nbytes); | |
$n = $this->binaryToLong($bytes); | |
// Keep looping if this value is in the low duplicated range | |
} while ($this->cmp($n, $duplicate) < 0); | |
return $this->mod($n, $stop); | |
} | |
} | |
/** | |
* Exposes BCmath math library functionality. | |
* | |
* {@link Auth_OpenID_BcMathWrapper} wraps the functionality provided | |
* by the BCMath extension. | |
* | |
* @access private | |
* @package OpenID | |
*/ | |
class Auth_OpenID_BcMathWrapper extends Auth_OpenID_MathLibrary{ | |
var $type = 'bcmath'; | |
function add($x, $y) | |
{ | |
return bcadd($x, $y); | |
} | |
function sub($x, $y) | |
{ | |
return bcsub($x, $y); | |
} | |
function pow($base, $exponent) | |
{ | |
return bcpow($base, $exponent); | |
} | |
function cmp($x, $y) | |
{ | |
return bccomp($x, $y); | |
} | |
function init($number, $base = 10) | |
{ | |
return $number; | |
} | |
function mod($base, $modulus) | |
{ | |
return bcmod($base, $modulus); | |
} | |
function mul($x, $y) | |
{ | |
return bcmul($x, $y); | |
} | |
function div($x, $y) | |
{ | |
return bcdiv($x, $y); | |
} | |
/** | |
* Same as bcpowmod when bcpowmod is missing | |
* | |
* @access private | |
*/ | |
function _powmod($base, $exponent, $modulus) | |
{ | |
$square = $this->mod($base, $modulus); | |
$result = 1; | |
while($this->cmp($exponent, 0) > 0) { | |
if ($this->mod($exponent, 2)) { | |
$result = $this->mod($this->mul($result, $square), $modulus); | |
} | |
$square = $this->mod($this->mul($square, $square), $modulus); | |
$exponent = $this->div($exponent, 2); | |
} | |
return $result; | |
} | |
function powmod($base, $exponent, $modulus) | |
{ | |
if (function_exists('bcpowmod')) { | |
return bcpowmod($base, $exponent, $modulus); | |
} else { | |
return $this->_powmod($base, $exponent, $modulus); | |
} | |
} | |
function toString($num) | |
{ | |
return $num; | |
} | |
} | |
/** | |
* Exposes GMP math library functionality. | |
* | |
* {@link Auth_OpenID_GmpMathWrapper} wraps the functionality provided | |
* by the GMP extension. | |
* | |
* @access private | |
* @package OpenID | |
*/ | |
class Auth_OpenID_GmpMathWrapper extends Auth_OpenID_MathLibrary{ | |
var $type = 'gmp'; | |
function add($x, $y) | |
{ | |
return gmp_add($x, $y); | |
} | |
function sub($x, $y) | |
{ | |
return gmp_sub($x, $y); | |
} | |
function pow($base, $exponent) | |
{ | |
return gmp_pow($base, $exponent); | |
} | |
function cmp($x, $y) | |
{ | |
return gmp_cmp($x, $y); | |
} | |
function init($number, $base = 10) | |
{ | |
return gmp_init($number, $base); | |
} | |
function mod($base, $modulus) | |
{ | |
return gmp_mod($base, $modulus); | |
} | |
function mul($x, $y) | |
{ | |
return gmp_mul($x, $y); | |
} | |
function div($x, $y) | |
{ | |
return gmp_div_q($x, $y); | |
} | |
function powmod($base, $exponent, $modulus) | |
{ | |
return gmp_powm($base, $exponent, $modulus); | |
} | |
function toString($num) | |
{ | |
return gmp_strval($num); | |
} | |
} | |
/** | |
* Define the supported extensions. An extension array has keys | |
* 'modules', 'extension', and 'class'. 'modules' is an array of PHP | |
* module names which the loading code will attempt to load. These | |
* values will be suffixed with a library file extension (e.g. ".so"). | |
* 'extension' is the name of a PHP extension which will be tested | |
* before 'modules' are loaded. 'class' is the string name of a | |
* {@link Auth_OpenID_MathWrapper} subclass which should be | |
* instantiated if a given extension is present. | |
* | |
* You can define new math library implementations and add them to | |
* this array. | |
*/ | |
function Auth_OpenID_math_extensions() | |
{ | |
$result = array(); | |
if (!defined('Auth_OpenID_BUGGY_GMP')) { | |
$result[] = | |
array('modules' => array('gmp', 'php_gmp'), | |
'extension' => 'gmp', | |
'class' => 'Auth_OpenID_GmpMathWrapper'); | |
} | |
$result[] = array('modules' => array('bcmath', 'php_bcmath'), | |
'extension' => 'bcmath', | |
'class' => 'Auth_OpenID_BcMathWrapper'); | |
return $result; | |
} | |
/** | |
* Detect which (if any) math library is available | |
*/ | |
function Auth_OpenID_detectMathLibrary($exts) | |
{ | |
$loaded = false; | |
foreach ($exts as $extension) { | |
if (extension_loaded($extension['extension'])) { | |
return $extension; | |
} | |
} | |
return false; | |
} | |
/** | |
* {@link Auth_OpenID_getMathLib} checks for the presence of long | |
* number extension modules and returns an instance of | |
* {@link Auth_OpenID_MathWrapper} which exposes the module's | |
* functionality. | |
* | |
* Checks for the existence of an extension module described by the | |
* result of {@link Auth_OpenID_math_extensions()} and returns an | |
* instance of a wrapper for that extension module. If no extension | |
* module is found, an instance of {@link Auth_OpenID_MathWrapper} is | |
* returned, which wraps the native PHP integer implementation. The | |
* proper calling convention for this method is $lib = | |
* Auth_OpenID_getMathLib(). | |
* | |
* This function checks for the existence of specific long number | |
* implementations in the following order: GMP followed by BCmath. | |
* | |
* @return Auth_OpenID_MathWrapper $instance An instance of | |
* {@link Auth_OpenID_MathWrapper} or one of its subclasses | |
* | |
* @package OpenID | |
*/ | |
function Auth_OpenID_getMathLib() | |
{ | |
// The instance of Auth_OpenID_MathWrapper that we choose to | |
// supply will be stored here, so that subseqent calls to this | |
// method will return a reference to the same object. | |
static $lib = null; | |
if (isset($lib)) { | |
return $lib; | |
} | |
if (Auth_OpenID_noMathSupport()) { | |
$null = null; | |
return $null; | |
} | |
// If this method has not been called before, look at | |
// Auth_OpenID_math_extensions and try to find an extension that | |
// works. | |
$ext = Auth_OpenID_detectMathLibrary(Auth_OpenID_math_extensions()); | |
if ($ext === false) { | |
$tried = array(); | |
foreach (Auth_OpenID_math_extensions() as $extinfo) { | |
$tried[] = $extinfo['extension']; | |
} | |
$triedstr = implode(", ", $tried); | |
Auth_OpenID_setNoMathSupport(); | |
$result = null; | |
return $result; | |
} | |
// Instantiate a new wrapper | |
$class = $ext['class']; | |
$lib = new $class(); | |
return $lib; | |
} | |
function Auth_OpenID_setNoMathSupport() | |
{ | |
if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) { | |
define('Auth_OpenID_NO_MATH_SUPPORT', true); | |
} | |
} | |
function Auth_OpenID_noMathSupport() | |
{ | |
return defined('Auth_OpenID_NO_MATH_SUPPORT'); | |
} | |
<?php | <?php |
/** | /** |
* This module documents the main interface with the OpenID consumer | * This module documents the main interface with the OpenID consumer |
* library. The only part of the library which has to be used and | * library. The only part of the library which has to be used and |
* isn't documented in full here is the store required to create an | * isn't documented in full here is the store required to create an |
* Auth_OpenID_Consumer instance. More on the abstract store type and | * Auth_OpenID_Consumer instance. More on the abstract store type and |
* concrete implementations of it that are provided in the | * concrete implementations of it that are provided in the |
* documentation for the Auth_OpenID_Consumer constructor. | * documentation for the Auth_OpenID_Consumer constructor. |
* | * |
* OVERVIEW | * OVERVIEW |
* | * |
* The OpenID identity verification process most commonly uses the | * The OpenID identity verification process most commonly uses the |
* following steps, as visible to the user of this library: | * following steps, as visible to the user of this library: |
* | * |
* 1. The user enters their OpenID into a field on the consumer's | * 1. The user enters their OpenID into a field on the consumer's |
* site, and hits a login button. | * site, and hits a login button. |
* 2. The consumer site discovers the user's OpenID server using the | * 2. The consumer site discovers the user's OpenID server using the |
* YADIS protocol. | * YADIS protocol. |
* 3. The consumer site sends the browser a redirect to the identity | * 3. The consumer site sends the browser a redirect to the identity |
* server. This is the authentication request as described in | * server. This is the authentication request as described in |
* the OpenID specification. | * the OpenID specification. |
* 4. The identity server's site sends the browser a redirect back | * 4. The identity server's site sends the browser a redirect back |
* to the consumer site. This redirect contains the server's | * to the consumer site. This redirect contains the server's |
* response to the authentication request. | * response to the authentication request. |
* | * |
* The most important part of the flow to note is the consumer's site | * The most important part of the flow to note is the consumer's site |
* must handle two separate HTTP requests in order to perform the full | * must handle two separate HTTP requests in order to perform the full |
* identity check. | * identity check. |
* | * |
* LIBRARY DESIGN | * LIBRARY DESIGN |
* | * |
* This consumer library is designed with that flow in mind. The goal | * This consumer library is designed with that flow in mind. The goal |
* is to make it as easy as possible to perform the above steps | * is to make it as easy as possible to perform the above steps |
* securely. | * securely. |
* | * |
* At a high level, there are two important parts in the consumer | * At a high level, there are two important parts in the consumer |
* library. The first important part is this module, which contains | * library. The first important part is this module, which contains |
* the interface to actually use this library. The second is the | * the interface to actually use this library. The second is the |
* Auth_OpenID_Interface class, which describes the interface to use | * Auth_OpenID_Interface class, which describes the interface to use |
* if you need to create a custom method for storing the state this | * if you need to create a custom method for storing the state this |
* library needs to maintain between requests. | * library needs to maintain between requests. |
* | * |
* In general, the second part is less important for users of the | * In general, the second part is less important for users of the |
* library to know about, as several implementations are provided | * library to know about, as several implementations are provided |
* which cover a wide variety of situations in which consumers may use | * which cover a wide variety of situations in which consumers may use |
* the library. | * the library. |
* | * |
* This module contains a class, Auth_OpenID_Consumer, with methods | * This module contains a class, Auth_OpenID_Consumer, with methods |
* corresponding to the actions necessary in each of steps 2, 3, and 4 | * corresponding to the actions necessary in each of steps 2, 3, and 4 |
* described in the overview. Use of this library should be as easy | * described in the overview. Use of this library should be as easy |
* as creating an Auth_OpenID_Consumer instance and calling the | * as creating an Auth_OpenID_Consumer instance and calling the |
* methods appropriate for the action the site wants to take. | * methods appropriate for the action the site wants to take. |
* | * |
* STORES AND DUMB MODE | * STORES AND DUMB MODE |
* | * |
* OpenID is a protocol that works best when the consumer site is able | * OpenID is a protocol that works best when the consumer site is able |
* to store some state. This is the normal mode of operation for the | * to store some state. This is the normal mode of operation for the |
* protocol, and is sometimes referred to as smart mode. There is | * protocol, and is sometimes referred to as smart mode. There is |
* also a fallback mode, known as dumb mode, which is available when | * also a fallback mode, known as dumb mode, which is available when |
* the consumer site is not able to store state. This mode should be | * the consumer site is not able to store state. This mode should be |
* avoided when possible, as it leaves the implementation more | * avoided when possible, as it leaves the implementation more |
* vulnerable to replay attacks. | * vulnerable to replay attacks. |
* | * |
* The mode the library works in for normal operation is determined by | * The mode the library works in for normal operation is determined by |
* the store that it is given. The store is an abstraction that | * the store that it is given. The store is an abstraction that |
* handles the data that the consumer needs to manage between http | * handles the data that the consumer needs to manage between http |
* requests in order to operate efficiently and securely. | * requests in order to operate efficiently and securely. |
* | * |
* Several store implementation are provided, and the interface is | * Several store implementation are provided, and the interface is |
* fully documented so that custom stores can be used as well. See | * fully documented so that custom stores can be used as well. See |
* the documentation for the Auth_OpenID_Consumer class for more | * the documentation for the Auth_OpenID_Consumer class for more |
* information on the interface for stores. The implementations that | * information on the interface for stores. The implementations that |
* are provided allow the consumer site to store the necessary data in | * are provided allow the consumer site to store the necessary data in |
* several different ways, including several SQL databases and normal | * several different ways, including several SQL databases and normal |
* files on disk. | * files on disk. |
* | * |
* There is an additional concrete store provided that puts the system | * There is an additional concrete store provided that puts the system |
* in dumb mode. This is not recommended, as it removes the library's | * in dumb mode. This is not recommended, as it removes the library's |
* ability to stop replay attacks reliably. It still uses time-based | * ability to stop replay attacks reliably. It still uses time-based |
* checking to make replay attacks only possible within a small | * checking to make replay attacks only possible within a small |
* window, but they remain possible within that window. This store | * window, but they remain possible within that window. This store |
* should only be used if the consumer site has no way to retain data | * should only be used if the consumer site has no way to retain data |
* between requests at all. | * between requests at all. |
* | * |
* IMMEDIATE MODE | * IMMEDIATE MODE |
* | * |
* In the flow described above, the user may need to confirm to the | * In the flow described above, the user may need to confirm to the |
* lidentity server that it's ok to authorize his or her identity. | * lidentity server that it's ok to authorize his or her identity. |
* The server may draw pages asking for information from the user | * The server may draw pages asking for information from the user |
* before it redirects the browser back to the consumer's site. This | * before it redirects the browser back to the consumer's site. This |
* is generally transparent to the consumer site, so it is typically | * is generally transparent to the consumer site, so it is typically |
* ignored as an implementation detail. | * ignored as an implementation detail. |
* | * |
* There can be times, however, where the consumer site wants to get a | * There can be times, however, where the consumer site wants to get a |
* response immediately. When this is the case, the consumer can put | * response immediately. When this is the case, the consumer can put |
* the library in immediate mode. In immediate mode, there is an | * the library in immediate mode. In immediate mode, there is an |
* extra response possible from the server, which is essentially the | * extra response possible from the server, which is essentially the |
* server reporting that it doesn't have enough information to answer | * server reporting that it doesn't have enough information to answer |
* the question yet. | * the question yet. |
* | * |
* USING THIS LIBRARY | * USING THIS LIBRARY |
* | * |
* Integrating this library into an application is usually a | * Integrating this library into an application is usually a |
* relatively straightforward process. The process should basically | * relatively straightforward process. The process should basically |
* follow this plan: | * follow this plan: |
* | * |
* Add an OpenID login field somewhere on your site. When an OpenID | * Add an OpenID login field somewhere on your site. When an OpenID |
* is entered in that field and the form is submitted, it should make | * is entered in that field and the form is submitted, it should make |
* a request to the your site which includes that OpenID URL. | * a request to the your site which includes that OpenID URL. |
* | * |
* First, the application should instantiate the Auth_OpenID_Consumer | * First, the application should instantiate the Auth_OpenID_Consumer |
* class using the store of choice (Auth_OpenID_FileStore or one of | * class using the store of choice (Auth_OpenID_FileStore or one of |
* the SQL-based stores). If the application has a custom | * the SQL-based stores). If the application has a custom |
* session-management implementation, an object implementing the | * session-management implementation, an object implementing the |
* {@link Auth_Yadis_PHPSession} interface should be passed as the | * {@link Auth_Yadis_PHPSession} interface should be passed as the |
* second parameter. Otherwise, the default uses $_SESSION. | * second parameter. Otherwise, the default uses $_SESSION. |
* | * |
* Next, the application should call the Auth_OpenID_Consumer object's | * Next, the application should call the Auth_OpenID_Consumer object's |
* 'begin' method. This method takes the OpenID URL. The 'begin' | * 'begin' method. This method takes the OpenID URL. The 'begin' |
* method returns an Auth_OpenID_AuthRequest object. | * method returns an Auth_OpenID_AuthRequest object. |
* | * |
* Next, the application should call the 'redirectURL' method of the | * Next, the application should call the 'redirectURL' method of the |
* Auth_OpenID_AuthRequest object. The 'return_to' URL parameter is | * Auth_OpenID_AuthRequest object. The 'return_to' URL parameter is |
* the URL that the OpenID server will send the user back to after | * the URL that the OpenID server will send the user back to after |
* attempting to verify his or her identity. The 'trust_root' is the | * attempting to verify his or her identity. The 'trust_root' is the |
* URL (or URL pattern) that identifies your web site to the user when | * URL (or URL pattern) that identifies your web site to the user when |
* he or she is authorizing it. Send a redirect to the resulting URL | * he or she is authorizing it. Send a redirect to the resulting URL |
* to the user's browser. | * to the user's browser. |
* | * |
* That's the first half of the authentication process. The second | * That's the first half of the authentication process. The second |
* half of the process is done after the user's ID server sends the | * half of the process is done after the user's ID server sends the |
* user's browser a redirect back to your site to complete their | * user's browser a redirect back to your site to complete their |
* login. | * login. |
* | * |
* When that happens, the user will contact your site at the URL given | * When that happens, the user will contact your site at the URL given |
* as the 'return_to' URL to the Auth_OpenID_AuthRequest::redirectURL | * as the 'return_to' URL to the Auth_OpenID_AuthRequest::redirectURL |
* call made above. The request will have several query parameters | * call made above. The request will have several query parameters |
* added to the URL by the identity server as the information | * added to the URL by the identity server as the information |
* necessary to finish the request. | * necessary to finish the request. |
* | * |
* Lastly, instantiate an Auth_OpenID_Consumer instance as above and | * Lastly, instantiate an Auth_OpenID_Consumer instance as above and |
* call its 'complete' method, passing in all the received query | * call its 'complete' method, passing in all the received query |
* arguments. | * arguments. |
* | * |
* There are multiple possible return types possible from that | * There are multiple possible return types possible from that |
* method. These indicate the whether or not the login was successful, | * method. These indicate the whether or not the login was successful, |
* and include any additional information appropriate for their type. | * and include any additional information appropriate for their type. |
* | * |
* PHP versions 4 and 5 | * PHP versions 4 and 5 |
* | * |
* LICENSE: See the COPYING file included in this distribution. | * LICENSE: See the COPYING file included in this distribution. |
* | * |
* @package OpenID | * @package OpenID |
* @author JanRain, Inc. <openid@janrain.com> | * @author JanRain, Inc. <openid@janrain.com> |
* @copyright 2005-2008 Janrain, Inc. | * @copyright 2005-2008 Janrain, Inc. |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache |
*/ | */ |
/** | /** |
* Require utility classes and functions for the consumer. | * Require utility classes and functions for the consumer. |
*/ | */ |
require_once "Auth/OpenID.php"; | require_once "Auth/OpenID.php"; |
require_once "Auth/OpenID/Message.php"; | require_once "Auth/OpenID/Message.php"; |
require_once "Auth/OpenID/HMAC.php"; | require_once "Auth/OpenID/HMAC.php"; |
require_once "Auth/OpenID/Association.php"; | require_once "Auth/OpenID/Association.php"; |
require_once "Auth/OpenID/CryptUtil.php"; | require_once "Auth/OpenID/CryptUtil.php"; |
require_once "Auth/OpenID/DiffieHellman.php"; | require_once "Auth/OpenID/DiffieHellman.php"; |
require_once "Auth/OpenID/KVForm.php"; | require_once "Auth/OpenID/KVForm.php"; |
require_once "Auth/OpenID/Nonce.php"; | require_once "Auth/OpenID/Nonce.php"; |
require_once "Auth/OpenID/Discover.php"; | require_once "Auth/OpenID/Discover.php"; |
require_once "Auth/OpenID/URINorm.php"; | require_once "Auth/OpenID/URINorm.php"; |
require_once "Auth/Yadis/Manager.php"; | require_once "Auth/Yadis/Manager.php"; |
require_once "Auth/Yadis/XRI.php"; | require_once "Auth/Yadis/XRI.php"; |
/** | /** |
* This is the status code returned when the complete method returns | * This is the status code returned when the complete method returns |
* successfully. | * successfully. |
*/ | */ |
define('Auth_OpenID_SUCCESS', 'success'); | define('Auth_OpenID_SUCCESS', 'success'); |
/** | /** |
* Status to indicate cancellation of OpenID authentication. | * Status to indicate cancellation of OpenID authentication. |
*/ | */ |
define('Auth_OpenID_CANCEL', 'cancel'); | define('Auth_OpenID_CANCEL', 'cancel'); |
/** | /** |
* This is the status code completeAuth returns when the value it | * This is the status code completeAuth returns when the value it |
* received indicated an invalid login. | * received indicated an invalid login. |
*/ | */ |
define('Auth_OpenID_FAILURE', 'failure'); | define('Auth_OpenID_FAILURE', 'failure'); |
/** | /** |
* This is the status code completeAuth returns when the | * This is the status code completeAuth returns when the |
* {@link Auth_OpenID_Consumer} instance is in immediate mode, and the | * {@link Auth_OpenID_Consumer} instance is in immediate mode, and the |
* identity server sends back a URL to send the user to to complete his | * identity server sends back a URL to send the user to to complete his |
* or her login. | * or her login. |
*/ | */ |
define('Auth_OpenID_SETUP_NEEDED', 'setup needed'); | define('Auth_OpenID_SETUP_NEEDED', 'setup needed'); |
/** | /** |
* This is the status code beginAuth returns when the page fetched | * This is the status code beginAuth returns when the page fetched |
* from the entered OpenID URL doesn't contain the necessary link tags | * from the entered OpenID URL doesn't contain the necessary link tags |
* to function as an identity page. | * to function as an identity page. |
*/ | */ |
define('Auth_OpenID_PARSE_ERROR', 'parse error'); | define('Auth_OpenID_PARSE_ERROR', 'parse error'); |
/** | /** |
* An OpenID consumer implementation that performs discovery and does | * An OpenID consumer implementation that performs discovery and does |
* session management. See the Consumer.php file documentation for | * session management. See the Consumer.php file documentation for |
* more information. | * more information. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_Consumer { | class Auth_OpenID_Consumer { |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $discoverMethod = 'Auth_OpenID_discover'; | var $discoverMethod = 'Auth_OpenID_discover'; |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $session_key_prefix = "_openid_consumer_"; | var $session_key_prefix = "_openid_consumer_"; |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $_token_suffix = "last_token"; | var $_token_suffix = "last_token"; |
/** | /** |
* Initialize a Consumer instance. | * Initialize a Consumer instance. |
* | * |
* You should create a new instance of the Consumer object with | * You should create a new instance of the Consumer object with |
* every HTTP request that handles OpenID transactions. | * every HTTP request that handles OpenID transactions. |
* | * |
* @param Auth_OpenID_OpenIDStore $store This must be an object | * @param Auth_OpenID_OpenIDStore $store This must be an object |
* that implements the interface in {@link | * that implements the interface in {@link |
* Auth_OpenID_OpenIDStore}. Several concrete implementations are | * Auth_OpenID_OpenIDStore}. Several concrete implementations are |
* provided, to cover most common use cases. For stores backed by | * provided, to cover most common use cases. For stores backed by |
* MySQL, PostgreSQL, or SQLite, see the {@link | * MySQL, PostgreSQL, or SQLite, see the {@link |
* Auth_OpenID_SQLStore} class and its sublcasses. For a | * Auth_OpenID_SQLStore} class and its sublcasses. For a |
* filesystem-backed store, see the {@link Auth_OpenID_FileStore} | * filesystem-backed store, see the {@link Auth_OpenID_FileStore} |
* module. As a last resort, if it isn't possible for the server | * module. As a last resort, if it isn't possible for the server |
* to store state at all, an instance of {@link | * to store state at all, an instance of {@link |
* Auth_OpenID_DumbStore} can be used. | * Auth_OpenID_DumbStore} can be used. |
* | * |
* @param mixed $session An object which implements the interface | * @param mixed $session An object which implements the interface |
* of the {@link Auth_Yadis_PHPSession} class. Particularly, this | * of the {@link Auth_Yadis_PHPSession} class. Particularly, this |
* object is expected to have these methods: get($key), set($key), | * object is expected to have these methods: get($key), set($key), |
* $value), and del($key). This defaults to a session object | * $value), and del($key). This defaults to a session object |
* which wraps PHP's native session machinery. You should only | * which wraps PHP's native session machinery. You should only |
* need to pass something here if you have your own sessioning | * need to pass something here if you have your own sessioning |
* implementation. | * implementation. |
* | * |
* @param str $consumer_cls The name of the class to instantiate | * @param str $consumer_cls The name of the class to instantiate |
* when creating the internal consumer object. This is used for | * when creating the internal consumer object. This is used for |
* testing. | * testing. |
*/ | */ |
function Auth_OpenID_Consumer($store, $session = null, | function Auth_OpenID_Consumer($store, $session = null, |
$consumer_cls = null) | $consumer_cls = null) |
{ | { |
if ($session === null) { | if ($session === null) { |
$session = new Auth_Yadis_PHPSession(); | $session = new Auth_Yadis_PHPSession(); |
} | } |
$this->session = $session; | $this->session = $session; |
if ($consumer_cls !== null) { | if ($consumer_cls !== null) { |
$this->consumer = new $consumer_cls($store); | $this->consumer = new $consumer_cls($store); |
} else { | } else { |
$this->consumer = new Auth_OpenID_GenericConsumer($store); | $this->consumer = new Auth_OpenID_GenericConsumer($store); |
} | } |
$this->_token_key = $this->session_key_prefix . $this->_token_suffix; | $this->_token_key = $this->session_key_prefix . $this->_token_suffix; |
} | } |
/** | /** |
* Used in testing to define the discovery mechanism. | * Used in testing to define the discovery mechanism. |
* | * |
* @access private | * @access private |
*/ | */ |
function getDiscoveryObject($session, $openid_url, | function getDiscoveryObject($session, $openid_url, |
$session_key_prefix) | $session_key_prefix) |
{ | { |
return new Auth_Yadis_Discovery($session, $openid_url, | return new Auth_Yadis_Discovery($session, $openid_url, |
$session_key_prefix); | $session_key_prefix); |
} | } |
/** | /** |
* Start the OpenID authentication process. See steps 1-2 in the | * Start the OpenID authentication process. See steps 1-2 in the |
* overview at the top of this file. | * overview at the top of this file. |
* | * |
* @param string $user_url Identity URL given by the user. This | * @param string $user_url Identity URL given by the user. This |
* method performs a textual transformation of the URL to try and | * method performs a textual transformation of the URL to try and |
* make sure it is normalized. For example, a user_url of | * make sure it is normalized. For example, a user_url of |
* example.com will be normalized to http://example.com/ | * example.com will be normalized to http://example.com/ |
* normalizing and resolving any redirects the server might issue. | * normalizing and resolving any redirects the server might issue. |
* | * |
* @param bool $anonymous True if the OpenID request is to be sent | * @param bool $anonymous True if the OpenID request is to be sent |
* to the server without any identifier information. Use this | * to the server without any identifier information. Use this |
* when you want to transport data but don't want to do OpenID | * when you want to transport data but don't want to do OpenID |
* authentication with identifiers. | * authentication with identifiers. |
* | * |
* @return Auth_OpenID_AuthRequest $auth_request An object | * @return Auth_OpenID_AuthRequest $auth_request An object |
* containing the discovered information will be returned, with a | * containing the discovered information will be returned, with a |
* method for building a redirect URL to the server, as described | * method for building a redirect URL to the server, as described |
* in step 3 of the overview. This object may also be used to add | * in step 3 of the overview. This object may also be used to add |
* extension arguments to the request, using its 'addExtensionArg' | * extension arguments to the request, using its 'addExtensionArg' |
* method. | * method. |
*/ | */ |
function begin($user_url, $anonymous=false) | function begin($user_url, $anonymous=false) |
{ | { |
$openid_url = $user_url; | $openid_url = $user_url; |
$disco = $this->getDiscoveryObject($this->session, | $disco = $this->getDiscoveryObject($this->session, |
$openid_url, | $openid_url, |
$this->session_key_prefix); | $this->session_key_prefix); |
// Set the 'stale' attribute of the manager. If discovery | // Set the 'stale' attribute of the manager. If discovery |
// fails in a fatal way, the stale flag will cause the manager | // fails in a fatal way, the stale flag will cause the manager |
// to be cleaned up next time discovery is attempted. | // to be cleaned up next time discovery is attempted. |
$m = $disco->getManager(); | $m = $disco->getManager(); |
$loader = new Auth_Yadis_ManagerLoader(); | $loader = new Auth_Yadis_ManagerLoader(); |
if ($m) { | if ($m) { |
if ($m->stale) { | if ($m->stale) { |
$disco->destroyManager(); | $disco->destroyManager(); |
} else { | } else { |
$m->stale = true; | $m->stale = true; |
$disco->session->set($disco->session_key, | $disco->session->set($disco->session_key, |
serialize($loader->toSession($m))); | serialize($loader->toSession($m))); |
} | } |
} | } |
$endpoint = $disco->getNextService($this->discoverMethod, | $endpoint = $disco->getNextService($this->discoverMethod, |
$this->consumer->fetcher); | $this->consumer->fetcher); |
// Reset the 'stale' attribute of the manager. | // Reset the 'stale' attribute of the manager. |
$m = $disco->getManager(); | $m = $disco->getManager(); |
if ($m) { | if ($m) { |
$m->stale = false; | $m->stale = false; |
$disco->session->set($disco->session_key, | $disco->session->set($disco->session_key, |
serialize($loader->toSession($m))); | serialize($loader->toSession($m))); |
} | } |
if ($endpoint === null) { | if ($endpoint === null) { |
return null; | return null; |
} else { | } else { |
return $this->beginWithoutDiscovery($endpoint, | return $this->beginWithoutDiscovery($endpoint, |
$anonymous); | $anonymous); |
} | } |
} | } |
/** | /** |
* Start OpenID verification without doing OpenID server | * Start OpenID verification without doing OpenID server |
* discovery. This method is used internally by Consumer.begin | * discovery. This method is used internally by Consumer.begin |
* after discovery is performed, and exists to provide an | * after discovery is performed, and exists to provide an |
* interface for library users needing to perform their own | * interface for library users needing to perform their own |
* discovery. | * discovery. |
* | * |
* @param Auth_OpenID_ServiceEndpoint $endpoint an OpenID service | * @param Auth_OpenID_ServiceEndpoint $endpoint an OpenID service |
* endpoint descriptor. | * endpoint descriptor. |
* | * |
* @param bool anonymous Set to true if you want to perform OpenID | * @param bool anonymous Set to true if you want to perform OpenID |
* without identifiers. | * without identifiers. |
* | * |
* @return Auth_OpenID_AuthRequest $auth_request An OpenID | * @return Auth_OpenID_AuthRequest $auth_request An OpenID |
* authentication request object. | * authentication request object. |
*/ | */ |
function beginWithoutDiscovery($endpoint, $anonymous=false) | function beginWithoutDiscovery($endpoint, $anonymous=false) |
{ | { |
$loader = new Auth_OpenID_ServiceEndpointLoader(); | $loader = new Auth_OpenID_ServiceEndpointLoader(); |
$auth_req = $this->consumer->begin($endpoint); | $auth_req = $this->consumer->begin($endpoint); |
$this->session->set($this->_token_key, | $this->session->set($this->_token_key, |
$loader->toSession($auth_req->endpoint)); | $loader->toSession($auth_req->endpoint)); |
if (!$auth_req->setAnonymous($anonymous)) { | if (!$auth_req->setAnonymous($anonymous)) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"OpenID 1 requests MUST include the identifier " . | "OpenID 1 requests MUST include the identifier " . |
"in the request."); | "in the request."); |
} | } |
return $auth_req; | return $auth_req; |
} | } |
/** | /** |
* Called to interpret the server's response to an OpenID | * Called to interpret the server's response to an OpenID |
* request. It is called in step 4 of the flow described in the | * request. It is called in step 4 of the flow described in the |
* consumer overview. | * consumer overview. |
* | * |
* @param string $current_url The URL used to invoke the application. | * @param string $current_url The URL used to invoke the application. |
* Extract the URL from your application's web | * Extract the URL from your application's web |
* request framework and specify it here to have it checked | * request framework and specify it here to have it checked |
* against the openid.current_url value in the response. If | * against the openid.current_url value in the response. If |
* the current_url URL check fails, the status of the | * the current_url URL check fails, the status of the |
* completion will be FAILURE. | * completion will be FAILURE. |
* | * |
* @param array $query An array of the query parameters (key => | * @param array $query An array of the query parameters (key => |
* value pairs) for this HTTP request. Defaults to null. If | * value pairs) for this HTTP request. Defaults to null. If |
* null, the GET or POST data are automatically gotten from the | * null, the GET or POST data are automatically gotten from the |
* PHP environment. It is only useful to override $query for | * PHP environment. It is only useful to override $query for |
* testing. | * testing. |
* | * |
* @return Auth_OpenID_ConsumerResponse $response A instance of an | * @return Auth_OpenID_ConsumerResponse $response A instance of an |
* Auth_OpenID_ConsumerResponse subclass. The type of response is | * Auth_OpenID_ConsumerResponse subclass. The type of response is |
* indicated by the status attribute, which will be one of | * indicated by the status attribute, which will be one of |
* SUCCESS, CANCEL, FAILURE, or SETUP_NEEDED. | * SUCCESS, CANCEL, FAILURE, or SETUP_NEEDED. |
*/ | */ |
function complete($current_url, $query=null) | function complete($current_url, $query=null) |
{ | { |
if ($current_url && !is_string($current_url)) { | if ($current_url && !is_string($current_url)) { |
// This is ugly, but we need to complain loudly when | // This is ugly, but we need to complain loudly when |
// someone uses the API incorrectly. | // someone uses the API incorrectly. |
trigger_error("current_url must be a string; see NEWS file " . | trigger_error("current_url must be a string; see NEWS file " . |
"for upgrading notes.", | "for upgrading notes.", |
E_USER_ERROR); | E_USER_ERROR); |
} | } |
if ($query === null) { | if ($query === null) { |
$query = Auth_OpenID::getQuery(); | $query = Auth_OpenID::getQuery(); |
} | } |
$loader = new Auth_OpenID_ServiceEndpointLoader(); | $loader = new Auth_OpenID_ServiceEndpointLoader(); |
$endpoint_data = $this->session->get($this->_token_key); | $endpoint_data = $this->session->get($this->_token_key); |
$endpoint = | $endpoint = |
$loader->fromSession($endpoint_data); | $loader->fromSession($endpoint_data); |
$message = Auth_OpenID_Message::fromPostArgs($query); | $message = Auth_OpenID_Message::fromPostArgs($query); |
$response = $this->consumer->complete($message, $endpoint, | $response = $this->consumer->complete($message, $endpoint, |
$current_url); | $current_url); |
$this->session->del($this->_token_key); | $this->session->del($this->_token_key); |
if (in_array($response->status, array(Auth_OpenID_SUCCESS, | if (in_array($response->status, array(Auth_OpenID_SUCCESS, |
Auth_OpenID_CANCEL))) { | Auth_OpenID_CANCEL))) { |
if ($response->identity_url !== null) { | if ($response->identity_url !== null) { |
$disco = $this->getDiscoveryObject($this->session, | $disco = $this->getDiscoveryObject($this->session, |
$response->identity_url, | $response->identity_url, |
$this->session_key_prefix); | $this->session_key_prefix); |
$disco->cleanup(true); | $disco->cleanup(true); |
} | } |
} | } |
return $response; | return $response; |
} | } |
} | } |
/** | /** |
* A class implementing HMAC/DH-SHA1 consumer sessions. | * A class implementing HMAC/DH-SHA1 consumer sessions. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_DiffieHellmanSHA1ConsumerSession { | class Auth_OpenID_DiffieHellmanSHA1ConsumerSession { |
var $session_type = 'DH-SHA1'; | var $session_type = 'DH-SHA1'; |
var $hash_func = 'Auth_OpenID_SHA1'; | var $hash_func = 'Auth_OpenID_SHA1'; |
var $secret_size = 20; | var $secret_size = 20; |
var $allowed_assoc_types = array('HMAC-SHA1'); | var $allowed_assoc_types = array('HMAC-SHA1'); |
function Auth_OpenID_DiffieHellmanSHA1ConsumerSession($dh = null) | function Auth_OpenID_DiffieHellmanSHA1ConsumerSession($dh = null) |
{ | { |
if ($dh === null) { | if ($dh === null) { |
$dh = new Auth_OpenID_DiffieHellman(); | $dh = new Auth_OpenID_DiffieHellman(); |
} | } |
$this->dh = $dh; | $this->dh = $dh; |
} | } |
function getRequest() | function getRequest() |
{ | { |
$math = Auth_OpenID_getMathLib(); | $math = Auth_OpenID_getMathLib(); |
$cpub = $math->longToBase64($this->dh->public); | $cpub = $math->longToBase64($this->dh->public); |
$args = array('dh_consumer_public' => $cpub); | $args = array('dh_consumer_public' => $cpub); |
if (!$this->dh->usingDefaultValues()) { | if (!$this->dh->usingDefaultValues()) { |
$args = array_merge($args, array( | $args = array_merge($args, array( |
'dh_modulus' => | 'dh_modulus' => |
$math->longToBase64($this->dh->mod), | $math->longToBase64($this->dh->mod), |
'dh_gen' => | 'dh_gen' => |
$math->longToBase64($this->dh->gen))); | $math->longToBase64($this->dh->gen))); |
} | } |
return $args; | return $args; |
} | } |
function extractSecret($response) | function extractSecret($response) |
{ | { |
if (!$response->hasKey(Auth_OpenID_OPENID_NS, | if (!$response->hasKey(Auth_OpenID_OPENID_NS, |
'dh_server_public')) { | 'dh_server_public')) { |
return null; | return null; |
} | } |
if (!$response->hasKey(Auth_OpenID_OPENID_NS, | if (!$response->hasKey(Auth_OpenID_OPENID_NS, |
'enc_mac_key')) { | 'enc_mac_key')) { |
return null; | return null; |
} | } |
$math = Auth_OpenID_getMathLib(); | $math = Auth_OpenID_getMathLib(); |
$spub = $math->base64ToLong($response->getArg(Auth_OpenID_OPENID_NS, | $spub = $math->base64ToLong($response->getArg(Auth_OpenID_OPENID_NS, |
'dh_server_public')); | 'dh_server_public')); |
$enc_mac_key = base64_decode($response->getArg(Auth_OpenID_OPENID_NS, | $enc_mac_key = base64_decode($response->getArg(Auth_OpenID_OPENID_NS, |
'enc_mac_key')); | 'enc_mac_key')); |
return $this->dh->xorSecret($spub, $enc_mac_key, $this->hash_func); | return $this->dh->xorSecret($spub, $enc_mac_key, $this->hash_func); |
} | } |
} | } |
/** | /** |
* A class implementing HMAC/DH-SHA256 consumer sessions. | * A class implementing HMAC/DH-SHA256 consumer sessions. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_DiffieHellmanSHA256ConsumerSession extends | class Auth_OpenID_DiffieHellmanSHA256ConsumerSession extends |
Auth_OpenID_DiffieHellmanSHA1ConsumerSession { | Auth_OpenID_DiffieHellmanSHA1ConsumerSession { |
var $session_type = 'DH-SHA256'; | var $session_type = 'DH-SHA256'; |
var $hash_func = 'Auth_OpenID_SHA256'; | var $hash_func = 'Auth_OpenID_SHA256'; |
var $secret_size = 32; | var $secret_size = 32; |
var $allowed_assoc_types = array('HMAC-SHA256'); | var $allowed_assoc_types = array('HMAC-SHA256'); |
} | } |
/** | /** |
* A class implementing plaintext consumer sessions. | * A class implementing plaintext consumer sessions. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_PlainTextConsumerSession { | class Auth_OpenID_PlainTextConsumerSession { |
var $session_type = 'no-encryption'; | var $session_type = 'no-encryption'; |
var $allowed_assoc_types = array('HMAC-SHA1', 'HMAC-SHA256'); | var $allowed_assoc_types = array('HMAC-SHA1', 'HMAC-SHA256'); |
function getRequest() | function getRequest() |
{ | { |
return array(); | return array(); |
} | } |
function extractSecret($response) | function extractSecret($response) |
{ | { |
if (!$response->hasKey(Auth_OpenID_OPENID_NS, 'mac_key')) { | if (!$response->hasKey(Auth_OpenID_OPENID_NS, 'mac_key')) { |
return null; | return null; |
} | } |
return base64_decode($response->getArg(Auth_OpenID_OPENID_NS, | return base64_decode($response->getArg(Auth_OpenID_OPENID_NS, |
'mac_key')); | 'mac_key')); |
} | } |
} | } |
/** | /** |
* Returns available session types. | * Returns available session types. |
*/ | */ |
function Auth_OpenID_getAvailableSessionTypes() | function Auth_OpenID_getAvailableSessionTypes() |
{ | { |
$types = array( | $types = array( |
'no-encryption' => 'Auth_OpenID_PlainTextConsumerSession', | 'no-encryption' => 'Auth_OpenID_PlainTextConsumerSession', |
'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ConsumerSession', | 'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ConsumerSession', |
'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ConsumerSession'); | 'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ConsumerSession'); |
return $types; | return $types; |
} | } |
/** | /** |
* This class is the interface to the OpenID consumer logic. | * This class is the interface to the OpenID consumer logic. |
* Instances of it maintain no per-request state, so they can be | * Instances of it maintain no per-request state, so they can be |
* reused (or even used by multiple threads concurrently) as needed. | * reused (or even used by multiple threads concurrently) as needed. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_GenericConsumer { | class Auth_OpenID_GenericConsumer { |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $discoverMethod = 'Auth_OpenID_discover'; | var $discoverMethod = 'Auth_OpenID_discover'; |
/** | /** |
* This consumer's store object. | * This consumer's store object. |
*/ | */ |
var $store; | var $store; |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $_use_assocs; | var $_use_assocs; |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $openid1_nonce_query_arg_name = 'janrain_nonce'; | var $openid1_nonce_query_arg_name = 'janrain_nonce'; |
/** | /** |
* Another query parameter that gets added to the return_to for | * Another query parameter that gets added to the return_to for |
* OpenID 1; if the user's session state is lost, use this claimed | * OpenID 1; if the user's session state is lost, use this claimed |
* identifier to do discovery when verifying the response. | * identifier to do discovery when verifying the response. |
*/ | */ |
var $openid1_return_to_identifier_name = 'openid1_claimed_id'; | var $openid1_return_to_identifier_name = 'openid1_claimed_id'; |
/** | /** |
* This method initializes a new {@link Auth_OpenID_Consumer} | * This method initializes a new {@link Auth_OpenID_Consumer} |
* instance to access the library. | * instance to access the library. |
* | * |
* @param Auth_OpenID_OpenIDStore $store This must be an object | * @param Auth_OpenID_OpenIDStore $store This must be an object |
* that implements the interface in {@link Auth_OpenID_OpenIDStore}. | * that implements the interface in {@link Auth_OpenID_OpenIDStore}. |
* Several concrete implementations are provided, to cover most common use | * Several concrete implementations are provided, to cover most common use |
* cases. For stores backed by MySQL, PostgreSQL, or SQLite, see | * cases. For stores backed by MySQL, PostgreSQL, or SQLite, see |
* the {@link Auth_OpenID_SQLStore} class and its sublcasses. For a | * the {@link Auth_OpenID_SQLStore} class and its sublcasses. For a |
* filesystem-backed store, see the {@link Auth_OpenID_FileStore} module. | * filesystem-backed store, see the {@link Auth_OpenID_FileStore} module. |
* As a last resort, if it isn't possible for the server to store | * As a last resort, if it isn't possible for the server to store |
* state at all, an instance of {@link Auth_OpenID_DumbStore} can be used. | * state at all, an instance of {@link Auth_OpenID_DumbStore} can be used. |
* | * |
* @param bool $immediate This is an optional boolean value. It | * @param bool $immediate This is an optional boolean value. It |
* controls whether the library uses immediate mode, as explained | * controls whether the library uses immediate mode, as explained |
* in the module description. The default value is False, which | * in the module description. The default value is False, which |
* disables immediate mode. | * disables immediate mode. |
*/ | */ |
function Auth_OpenID_GenericConsumer($store) | function Auth_OpenID_GenericConsumer($store) |
{ | { |
$this->store = $store; | $this->store = $store; |
$this->negotiator = Auth_OpenID_getDefaultNegotiator(); | $this->negotiator = Auth_OpenID_getDefaultNegotiator(); |
$this->_use_assocs = (is_null($this->store) ? false : true); | $this->_use_assocs = (is_null($this->store) ? false : true); |
$this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); | $this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); |
$this->session_types = Auth_OpenID_getAvailableSessionTypes(); | $this->session_types = Auth_OpenID_getAvailableSessionTypes(); |
} | } |
/** | /** |
* Called to begin OpenID authentication using the specified | * Called to begin OpenID authentication using the specified |
* {@link Auth_OpenID_ServiceEndpoint}. | * {@link Auth_OpenID_ServiceEndpoint}. |
* | * |
* @access private | * @access private |
*/ | */ |
function begin($service_endpoint) | function begin($service_endpoint) |
{ | { |
$assoc = $this->_getAssociation($service_endpoint); | $assoc = $this->_getAssociation($service_endpoint); |
$r = new Auth_OpenID_AuthRequest($service_endpoint, $assoc); | $r = new Auth_OpenID_AuthRequest($service_endpoint, $assoc); |
$r->return_to_args[$this->openid1_nonce_query_arg_name] = | $r->return_to_args[$this->openid1_nonce_query_arg_name] = |
Auth_OpenID_mkNonce(); | Auth_OpenID_mkNonce(); |
if ($r->message->isOpenID1()) { | if ($r->message->isOpenID1()) { |
$r->return_to_args[$this->openid1_return_to_identifier_name] = | $r->return_to_args[$this->openid1_return_to_identifier_name] = |
$r->endpoint->claimed_id; | $r->endpoint->claimed_id; |
} | } |
return $r; | return $r; |
} | } |
/** | /** |
* Given an {@link Auth_OpenID_Message}, {@link | * Given an {@link Auth_OpenID_Message}, {@link |
* Auth_OpenID_ServiceEndpoint} and optional return_to URL, | * Auth_OpenID_ServiceEndpoint} and optional return_to URL, |
* complete OpenID authentication. | * complete OpenID authentication. |
* | * |
* @access private | * @access private |
*/ | */ |
function complete($message, $endpoint, $return_to) | function complete($message, $endpoint, $return_to) |
{ | { |
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode', | $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode', |
'<no mode set>'); | '<no mode set>'); |
$mode_methods = array( | $mode_methods = array( |
'cancel' => '_complete_cancel', | 'cancel' => '_complete_cancel', |
'error' => '_complete_error', | 'error' => '_complete_error', |
'setup_needed' => '_complete_setup_needed', | 'setup_needed' => '_complete_setup_needed', |
'id_res' => '_complete_id_res', | 'id_res' => '_complete_id_res', |
); | ); |
$method = Auth_OpenID::arrayGet($mode_methods, $mode, | $method = Auth_OpenID::arrayGet($mode_methods, $mode, |
'_completeInvalid'); | '_completeInvalid'); |
return call_user_func_array(array($this, $method), | return call_user_func_array(array($this, $method), |
array($message, &$endpoint, $return_to)); | array($message, &$endpoint, $return_to)); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _completeInvalid($message, $endpoint, $unused) | function _completeInvalid($message, $endpoint, $unused) |
{ | { |
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode', | $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode', |
'<No mode set>'); | '<No mode set>'); |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
sprintf("Invalid openid.mode '%s'", $mode)); | sprintf("Invalid openid.mode '%s'", $mode)); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _complete_cancel($message, $endpoint, $unused) | function _complete_cancel($message, $endpoint, $unused) |
{ | { |
return new Auth_OpenID_CancelResponse($endpoint); | return new Auth_OpenID_CancelResponse($endpoint); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _complete_error($message, $endpoint, $unused) | function _complete_error($message, $endpoint, $unused) |
{ | { |
$error = $message->getArg(Auth_OpenID_OPENID_NS, 'error'); | $error = $message->getArg(Auth_OpenID_OPENID_NS, 'error'); |
$contact = $message->getArg(Auth_OpenID_OPENID_NS, 'contact'); | $contact = $message->getArg(Auth_OpenID_OPENID_NS, 'contact'); |
$reference = $message->getArg(Auth_OpenID_OPENID_NS, 'reference'); | $reference = $message->getArg(Auth_OpenID_OPENID_NS, 'reference'); |
return new Auth_OpenID_FailureResponse($endpoint, $error, | return new Auth_OpenID_FailureResponse($endpoint, $error, |
$contact, $reference); | $contact, $reference); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _complete_setup_needed($message, $endpoint, $unused) | function _complete_setup_needed($message, $endpoint, $unused) |
{ | { |
if (!$message->isOpenID2()) { | if (!$message->isOpenID2()) { |
return $this->_completeInvalid($message, $endpoint); | return $this->_completeInvalid($message, $endpoint); |
} | } |
$user_setup_url = $message->getArg(Auth_OpenID_OPENID2_NS, | $user_setup_url = $message->getArg(Auth_OpenID_OPENID2_NS, |
'user_setup_url'); | 'user_setup_url'); |
return new Auth_OpenID_SetupNeededResponse($endpoint, $user_setup_url); | return new Auth_OpenID_SetupNeededResponse($endpoint, $user_setup_url); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _complete_id_res($message, $endpoint, $return_to) | function _complete_id_res($message, $endpoint, $return_to) |
{ | { |
$user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS, | $user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS, |
'user_setup_url'); | 'user_setup_url'); |
if ($this->_checkSetupNeeded($message)) { | if ($this->_checkSetupNeeded($message)) { |
return new Auth_OpenID_SetupNeededResponse( | return new Auth_OpenID_SetupNeededResponse( |
$endpoint, $user_setup_url); | $endpoint, $user_setup_url); |
} else { | } else { |
return $this->_doIdRes($message, $endpoint, $return_to); | return $this->_doIdRes($message, $endpoint, $return_to); |
} | } |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _checkSetupNeeded($message) | function _checkSetupNeeded($message) |
{ | { |
// In OpenID 1, we check to see if this is a cancel from | // In OpenID 1, we check to see if this is a cancel from |
// immediate mode by the presence of the user_setup_url | // immediate mode by the presence of the user_setup_url |
// parameter. | // parameter. |
if ($message->isOpenID1()) { | if ($message->isOpenID1()) { |
$user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS, | $user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS, |
'user_setup_url'); | 'user_setup_url'); |
if ($user_setup_url !== null) { | if ($user_setup_url !== null) { |
return true; | return true; |
} | } |
} | } |
return false; | return false; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _doIdRes($message, $endpoint, $return_to) | function _doIdRes($message, $endpoint, $return_to) |
{ | { |
// Checks for presence of appropriate fields (and checks | // Checks for presence of appropriate fields (and checks |
// signed list fields) | // signed list fields) |
$result = $this->_idResCheckForFields($message); | $result = $this->_idResCheckForFields($message); |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
return $result; | return $result; |
} | } |
if (!$this->_checkReturnTo($message, $return_to)) { | if (!$this->_checkReturnTo($message, $return_to)) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
sprintf("return_to does not match return URL. Expected %s, got %s", | sprintf("return_to does not match return URL. Expected %s, got %s", |
$return_to, | $return_to, |
$message->getArg(Auth_OpenID_OPENID_NS, 'return_to'))); | $message->getArg(Auth_OpenID_OPENID_NS, 'return_to'))); |
} | } |
// Verify discovery information: | // Verify discovery information: |
$result = $this->_verifyDiscoveryResults($message, $endpoint); | $result = $this->_verifyDiscoveryResults($message, $endpoint); |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
return $result; | return $result; |
} | } |
$endpoint = $result; | $endpoint = $result; |
$result = $this->_idResCheckSignature($message, | $result = $this->_idResCheckSignature($message, |
$endpoint->server_url); | $endpoint->server_url); |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
return $result; | return $result; |
} | } |
$result = $this->_idResCheckNonce($message, $endpoint); | $result = $this->_idResCheckNonce($message, $endpoint); |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
return $result; | return $result; |
} | } |
$signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, 'signed', | $signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, 'signed', |
Auth_OpenID_NO_DEFAULT); | Auth_OpenID_NO_DEFAULT); |
if (Auth_OpenID::isFailure($signed_list_str)) { | if (Auth_OpenID::isFailure($signed_list_str)) { |
return $signed_list_str; | return $signed_list_str; |
} | } |
$signed_list = explode(',', $signed_list_str); | $signed_list = explode(',', $signed_list_str); |
$signed_fields = Auth_OpenID::addPrefix($signed_list, "openid."); | $signed_fields = Auth_OpenID::addPrefix($signed_list, "openid."); |
return new Auth_OpenID_SuccessResponse($endpoint, $message, | return new Auth_OpenID_SuccessResponse($endpoint, $message, |
$signed_fields); | $signed_fields); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _checkReturnTo($message, $return_to) | function _checkReturnTo($message, $return_to) |
{ | { |
// Check an OpenID message and its openid.return_to value | // Check an OpenID message and its openid.return_to value |
// against a return_to URL from an application. Return True | // against a return_to URL from an application. Return True |
// on success, False on failure. | // on success, False on failure. |
// Check the openid.return_to args against args in the | // Check the openid.return_to args against args in the |
// original message. | // original message. |
$result = Auth_OpenID_GenericConsumer::_verifyReturnToArgs( | $result = Auth_OpenID_GenericConsumer::_verifyReturnToArgs( |
$message->toPostArgs()); | $message->toPostArgs()); |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
return false; | return false; |
} | } |
// Check the return_to base URL against the one in the | // Check the return_to base URL against the one in the |
// message. | // message. |
$msg_return_to = $message->getArg(Auth_OpenID_OPENID_NS, | $msg_return_to = $message->getArg(Auth_OpenID_OPENID_NS, |
'return_to'); | 'return_to'); |
if (Auth_OpenID::isFailure($return_to)) { | if (Auth_OpenID::isFailure($return_to)) { |
// XXX log me | // XXX log me |
return false; | return false; |
} | } |
$return_to_parts = parse_url(Auth_OpenID_urinorm($return_to)); | $return_to_parts = parse_url(Auth_OpenID_urinorm($return_to)); |
$msg_return_to_parts = parse_url(Auth_OpenID_urinorm($msg_return_to)); | $msg_return_to_parts = parse_url(Auth_OpenID_urinorm($msg_return_to)); |
// If port is absent from both, add it so it's equal in the | // If port is absent from both, add it so it's equal in the |
// check below. | // check below. |
if ((!array_key_exists('port', $return_to_parts)) && | if ((!array_key_exists('port', $return_to_parts)) && |
(!array_key_exists('port', $msg_return_to_parts))) { | (!array_key_exists('port', $msg_return_to_parts))) { |
$return_to_parts['port'] = null; | $return_to_parts['port'] = null; |
$msg_return_to_parts['port'] = null; | $msg_return_to_parts['port'] = null; |
} | } |
// If path is absent from both, add it so it's equal in the | // If path is absent from both, add it so it's equal in the |
// check below. | // check below. |
if ((!array_key_exists('path', $return_to_parts)) && | if ((!array_key_exists('path', $return_to_parts)) && |
(!array_key_exists('path', $msg_return_to_parts))) { | (!array_key_exists('path', $msg_return_to_parts))) { |
$return_to_parts['path'] = null; | $return_to_parts['path'] = null; |
$msg_return_to_parts['path'] = null; | $msg_return_to_parts['path'] = null; |
} | } |
// The URL scheme, authority, and path MUST be the same | // The URL scheme, authority, and path MUST be the same |
// between the two URLs. | // between the two URLs. |
foreach (array('scheme', 'host', 'port', 'path') as $component) { | foreach (array('scheme', 'host', 'port', 'path') as $component) { |
// If the url component is absent in either URL, fail. | // If the url component is absent in either URL, fail. |
// There should always be a scheme, host, port, and path. | // There should always be a scheme, host, port, and path. |
if (!array_key_exists($component, $return_to_parts)) { | if (!array_key_exists($component, $return_to_parts)) { |
return false; | return false; |
} | } |
if (!array_key_exists($component, $msg_return_to_parts)) { | if (!array_key_exists($component, $msg_return_to_parts)) { |
return false; | return false; |
} | } |
if (Auth_OpenID::arrayGet($return_to_parts, $component) !== | if (Auth_OpenID::arrayGet($return_to_parts, $component) !== |
Auth_OpenID::arrayGet($msg_return_to_parts, $component)) { | Auth_OpenID::arrayGet($msg_return_to_parts, $component)) { |
return false; | return false; |
} | } |
} | } |
return true; | return true; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _verifyReturnToArgs($query) | function _verifyReturnToArgs($query) |
{ | { |
// Verify that the arguments in the return_to URL are present in this | // Verify that the arguments in the return_to URL are present in this |
// response. | // response. |
$message = Auth_OpenID_Message::fromPostArgs($query); | $message = Auth_OpenID_Message::fromPostArgs($query); |
$return_to = $message->getArg(Auth_OpenID_OPENID_NS, 'return_to'); | $return_to = $message->getArg(Auth_OpenID_OPENID_NS, 'return_to'); |
if (Auth_OpenID::isFailure($return_to)) { | if (Auth_OpenID::isFailure($return_to)) { |
return $return_to; | return $return_to; |
} | } |
// XXX: this should be checked by _idResCheckForFields | // XXX: this should be checked by _idResCheckForFields |
if (!$return_to) { | if (!$return_to) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"Response has no return_to"); | "Response has no return_to"); |
} | } |
$parsed_url = parse_url($return_to); | $parsed_url = parse_url($return_to); |
$q = array(); | $q = array(); |
if (array_key_exists('query', $parsed_url)) { | if (array_key_exists('query', $parsed_url)) { |
$rt_query = $parsed_url['query']; | $rt_query = $parsed_url['query']; |
$q = Auth_OpenID::parse_str($rt_query); | $q = Auth_OpenID::parse_str($rt_query); |
} | } |
foreach ($q as $rt_key => $rt_value) { | foreach ($q as $rt_key => $rt_value) { |
if (!array_key_exists($rt_key, $query)) { | if (!array_key_exists($rt_key, $query)) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
sprintf("return_to parameter %s absent from query", $rt_key)); | sprintf("return_to parameter %s absent from query", $rt_key)); |
} else { | } else { |
$value = $query[$rt_key]; | $value = $query[$rt_key]; |
if ($rt_value != $value) { | if ($rt_value != $value) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
sprintf("parameter %s value %s does not match " . | sprintf("parameter %s value %s does not match " . |
"return_to value %s", $rt_key, | "return_to value %s", $rt_key, |
$value, $rt_value)); | $value, $rt_value)); |
} | } |
} | } |
} | } |
// Make sure all non-OpenID arguments in the response are also | // Make sure all non-OpenID arguments in the response are also |
// in the signed return_to. | // in the signed return_to. |
$bare_args = $message->getArgs(Auth_OpenID_BARE_NS); | $bare_args = $message->getArgs(Auth_OpenID_BARE_NS); |
foreach ($bare_args as $key => $value) { | foreach ($bare_args as $key => $value) { |
if (Auth_OpenID::arrayGet($q, $key) != $value) { | if (Auth_OpenID::arrayGet($q, $key) != $value) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
sprintf("Parameter %s = %s not in return_to URL", | sprintf("Parameter %s = %s not in return_to URL", |
$key, $value)); | $key, $value)); |
} | } |
} | } |
return true; | return true; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _idResCheckSignature($message, $server_url) | function _idResCheckSignature($message, $server_url) |
{ | { |
$assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, | $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, |
'assoc_handle'); | 'assoc_handle'); |
if (Auth_OpenID::isFailure($assoc_handle)) { | if (Auth_OpenID::isFailure($assoc_handle)) { |
return $assoc_handle; | return $assoc_handle; |
} | } |
$assoc = $this->store->getAssociation($server_url, $assoc_handle); | $assoc = $this->store->getAssociation($server_url, $assoc_handle); |
if ($assoc) { | if ($assoc) { |
if ($assoc->getExpiresIn() <= 0) { | if ($assoc->getExpiresIn() <= 0) { |
// XXX: It might be a good idea sometimes to re-start | // XXX: It might be a good idea sometimes to re-start |
// the authentication with a new association. Doing it | // the authentication with a new association. Doing it |
// automatically opens the possibility for | // automatically opens the possibility for |
// denial-of-service by a server that just returns | // denial-of-service by a server that just returns |
// expired associations (or really short-lived | // expired associations (or really short-lived |
// associations) | // associations) |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
'Association with ' . $server_url . ' expired'); | 'Association with ' . $server_url . ' expired'); |
} | } |
if (!$assoc->checkMessageSignature($message)) { | if (!$assoc->checkMessageSignature($message)) { |
// If we get a "bad signature" here, it means that the association | // If we get a "bad signature" here, it means that the association |
// is unrecoverabley corrupted in some way. Any futher attempts | // is unrecoverabley corrupted in some way. Any futher attempts |
// to login with this association is likely to fail. Drop it. | // to login with this association is likely to fail. Drop it. |
$this->store->removeAssociation($server_url, $assoc_handle); | $this->store->removeAssociation($server_url, $assoc_handle); |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"Bad signature"); | "Bad signature"); |
} | } |
} else { | } else { |
// It's not an association we know about. Stateless mode | // It's not an association we know about. Stateless mode |
// is our only possible path for recovery. XXX - async | // is our only possible path for recovery. XXX - async |
// framework will not want to block on this call to | // framework will not want to block on this call to |
// _checkAuth. | // _checkAuth. |
if (!$this->_checkAuth($message, $server_url)) { | if (!$this->_checkAuth($message, $server_url)) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"Server denied check_authentication"); | "Server denied check_authentication"); |
} | } |
} | } |
return null; | return null; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _verifyDiscoveryResults($message, $endpoint=null) | function _verifyDiscoveryResults($message, $endpoint=null) |
{ | { |
if ($message->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS) { | if ($message->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS) { |
return $this->_verifyDiscoveryResultsOpenID2($message, | return $this->_verifyDiscoveryResultsOpenID2($message, |
$endpoint); | $endpoint); |
} else { | } else { |
return $this->_verifyDiscoveryResultsOpenID1($message, | return $this->_verifyDiscoveryResultsOpenID1($message, |
$endpoint); | $endpoint); |
} | } |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _verifyDiscoveryResultsOpenID1($message, $endpoint) | function _verifyDiscoveryResultsOpenID1($message, $endpoint) |
{ | { |
$claimed_id = $message->getArg(Auth_OpenID_BARE_NS, | $claimed_id = $message->getArg(Auth_OpenID_BARE_NS, |
$this->openid1_return_to_identifier_name); | $this->openid1_return_to_identifier_name); |
if (($endpoint === null) && ($claimed_id === null)) { | if (($endpoint === null) && ($claimed_id === null)) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
'When using OpenID 1, the claimed ID must be supplied, ' . | 'When using OpenID 1, the claimed ID must be supplied, ' . |
'either by passing it through as a return_to parameter ' . | 'either by passing it through as a return_to parameter ' . |
'or by using a session, and supplied to the GenericConsumer ' . | 'or by using a session, and supplied to the GenericConsumer ' . |
'as the argument to complete()'); | 'as the argument to complete()'); |
} else if (($endpoint !== null) && ($claimed_id === null)) { | } else if (($endpoint !== null) && ($claimed_id === null)) { |
$claimed_id = $endpoint->claimed_id; | $claimed_id = $endpoint->claimed_id; |
} | } |
$to_match = new Auth_OpenID_ServiceEndpoint(); | $to_match = new Auth_OpenID_ServiceEndpoint(); |
$to_match->type_uris = array(Auth_OpenID_TYPE_1_1); | $to_match->type_uris = array(Auth_OpenID_TYPE_1_1); |
$to_match->local_id = $message->getArg(Auth_OpenID_OPENID1_NS, | $to_match->local_id = $message->getArg(Auth_OpenID_OPENID1_NS, |
'identity'); | 'identity'); |
// Restore delegate information from the initiation phase | // Restore delegate information from the initiation phase |
$to_match->claimed_id = $claimed_id; | $to_match->claimed_id = $claimed_id; |
if ($to_match->local_id === null) { | if ($to_match->local_id === null) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
"Missing required field openid.identity"); | "Missing required field openid.identity"); |
} | } |
$to_match_1_0 = $to_match->copy(); | $to_match_1_0 = $to_match->copy(); |
$to_match_1_0->type_uris = array(Auth_OpenID_TYPE_1_0); | $to_match_1_0->type_uris = array(Auth_OpenID_TYPE_1_0); |
if ($endpoint !== null) { | if ($endpoint !== null) { |
$result = $this->_verifyDiscoverySingle($endpoint, $to_match); | $result = $this->_verifyDiscoverySingle($endpoint, $to_match); |
if (is_a($result, 'Auth_OpenID_TypeURIMismatch')) { | if (is_a($result, 'Auth_OpenID_TypeURIMismatch')) { |
$result = $this->_verifyDiscoverySingle($endpoint, | $result = $this->_verifyDiscoverySingle($endpoint, |
$to_match_1_0); | $to_match_1_0); |
} | } |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
// oidutil.log("Error attempting to use stored | // oidutil.log("Error attempting to use stored |
// discovery information: " + str(e)) | // discovery information: " + str(e)) |
// oidutil.log("Attempting discovery to | // oidutil.log("Attempting discovery to |
// verify endpoint") | // verify endpoint") |
} else { | } else { |
return $endpoint; | return $endpoint; |
} | } |
} | } |
// Endpoint is either bad (failed verification) or None | // Endpoint is either bad (failed verification) or None |
return $this->_discoverAndVerify($to_match->claimed_id, | return $this->_discoverAndVerify($to_match->claimed_id, |
array($to_match, $to_match_1_0)); | array($to_match, $to_match_1_0)); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _verifyDiscoverySingle($endpoint, $to_match) | function _verifyDiscoverySingle($endpoint, $to_match) |
{ | { |
// Every type URI that's in the to_match endpoint has to be | // Every type URI that's in the to_match endpoint has to be |
// present in the discovered endpoint. | // present in the discovered endpoint. |
foreach ($to_match->type_uris as $type_uri) { | foreach ($to_match->type_uris as $type_uri) { |
if (!$endpoint->usesExtension($type_uri)) { | if (!$endpoint->usesExtension($type_uri)) { |
return new Auth_OpenID_TypeURIMismatch($endpoint, | return new Auth_OpenID_TypeURIMismatch($endpoint, |
"Required type ".$type_uri." not present"); | "Required type ".$type_uri." not present"); |
} | } |
} | } |
// Fragments do not influence discovery, so we can't compare a | // Fragments do not influence discovery, so we can't compare a |
// claimed identifier with a fragment to discovered | // claimed identifier with a fragment to discovered |
// information. | // information. |
list($defragged_claimed_id, $_) = | list($defragged_claimed_id, $_) = |
Auth_OpenID::urldefrag($to_match->claimed_id); | Auth_OpenID::urldefrag($to_match->claimed_id); |
if ($defragged_claimed_id != $endpoint->claimed_id) { | if ($defragged_claimed_id != $endpoint->claimed_id) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
sprintf('Claimed ID does not match (different subjects!), ' . | sprintf('Claimed ID does not match (different subjects!), ' . |
'Expected %s, got %s', $defragged_claimed_id, | 'Expected %s, got %s', $defragged_claimed_id, |
$endpoint->claimed_id)); | $endpoint->claimed_id)); |
} | } |
if ($to_match->getLocalID() != $endpoint->getLocalID()) { | if ($to_match->getLocalID() != $endpoint->getLocalID()) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
sprintf('local_id mismatch. Expected %s, got %s', | sprintf('local_id mismatch. Expected %s, got %s', |
$to_match->getLocalID(), $endpoint->getLocalID())); | $to_match->getLocalID(), $endpoint->getLocalID())); |
} | } |
// If the server URL is None, this must be an OpenID 1 | // If the server URL is None, this must be an OpenID 1 |
// response, because op_endpoint is a required parameter in | // response, because op_endpoint is a required parameter in |
// OpenID 2. In that case, we don't actually care what the | // OpenID 2. In that case, we don't actually care what the |
// discovered server_url is, because signature checking or | // discovered server_url is, because signature checking or |
// check_auth should take care of that check for us. | // check_auth should take care of that check for us. |
if ($to_match->server_url === null) { | if ($to_match->server_url === null) { |
if ($to_match->preferredNamespace() != Auth_OpenID_OPENID1_NS) { | if ($to_match->preferredNamespace() != Auth_OpenID_OPENID1_NS) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
"Preferred namespace mismatch (bug)"); | "Preferred namespace mismatch (bug)"); |
} | } |
} else if ($to_match->server_url != $endpoint->server_url) { | } else if ($to_match->server_url != $endpoint->server_url) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
sprintf('OP Endpoint mismatch. Expected %s, got %s', | sprintf('OP Endpoint mismatch. Expected %s, got %s', |
$to_match->server_url, $endpoint->server_url)); | $to_match->server_url, $endpoint->server_url)); |
} | } |
return null; | return null; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _verifyDiscoveryResultsOpenID2($message, $endpoint) | function _verifyDiscoveryResultsOpenID2($message, $endpoint) |
{ | { |
$to_match = new Auth_OpenID_ServiceEndpoint(); | $to_match = new Auth_OpenID_ServiceEndpoint(); |
$to_match->type_uris = array(Auth_OpenID_TYPE_2_0); | $to_match->type_uris = array(Auth_OpenID_TYPE_2_0); |
$to_match->claimed_id = $message->getArg(Auth_OpenID_OPENID2_NS, | $to_match->claimed_id = $message->getArg(Auth_OpenID_OPENID2_NS, |
'claimed_id'); | 'claimed_id'); |
$to_match->local_id = $message->getArg(Auth_OpenID_OPENID2_NS, | $to_match->local_id = $message->getArg(Auth_OpenID_OPENID2_NS, |
'identity'); | 'identity'); |
$to_match->server_url = $message->getArg(Auth_OpenID_OPENID2_NS, | $to_match->server_url = $message->getArg(Auth_OpenID_OPENID2_NS, |
'op_endpoint'); | 'op_endpoint'); |
if ($to_match->server_url === null) { | if ($to_match->server_url === null) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
"OP Endpoint URL missing"); | "OP Endpoint URL missing"); |
} | } |
// claimed_id and identifier must both be present or both be | // claimed_id and identifier must both be present or both be |
// absent | // absent |
if (($to_match->claimed_id === null) && | if (($to_match->claimed_id === null) && |
($to_match->local_id !== null)) { | ($to_match->local_id !== null)) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
'openid.identity is present without openid.claimed_id'); | 'openid.identity is present without openid.claimed_id'); |
} | } |
if (($to_match->claimed_id !== null) && | if (($to_match->claimed_id !== null) && |
($to_match->local_id === null)) { | ($to_match->local_id === null)) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
'openid.claimed_id is present without openid.identity'); | 'openid.claimed_id is present without openid.identity'); |
} | } |
if ($to_match->claimed_id === null) { | if ($to_match->claimed_id === null) { |
// This is a response without identifiers, so there's | // This is a response without identifiers, so there's |
// really no checking that we can do, so return an | // really no checking that we can do, so return an |
// endpoint that's for the specified `openid.op_endpoint' | // endpoint that's for the specified `openid.op_endpoint' |
return Auth_OpenID_ServiceEndpoint::fromOPEndpointURL( | return Auth_OpenID_ServiceEndpoint::fromOPEndpointURL( |
$to_match->server_url); | $to_match->server_url); |
} | } |
if (!$endpoint) { | if (!$endpoint) { |
// The claimed ID doesn't match, so we have to do | // The claimed ID doesn't match, so we have to do |
// discovery again. This covers not using sessions, OP | // discovery again. This covers not using sessions, OP |
// identifier endpoints and responses that didn't match | // identifier endpoints and responses that didn't match |
// the original request. | // the original request. |
// oidutil.log('No pre-discovered information supplied.') | // oidutil.log('No pre-discovered information supplied.') |
return $this->_discoverAndVerify($to_match->claimed_id, | return $this->_discoverAndVerify($to_match->claimed_id, |
array($to_match)); | array($to_match)); |
} else { | } else { |
// The claimed ID matches, so we use the endpoint that we | // The claimed ID matches, so we use the endpoint that we |
// discovered in initiation. This should be the most | // discovered in initiation. This should be the most |
// common case. | // common case. |
$result = $this->_verifyDiscoverySingle($endpoint, $to_match); | $result = $this->_verifyDiscoverySingle($endpoint, $to_match); |
if (Auth_OpenID::isFailure($result)) { | if (Auth_OpenID::isFailure($result)) { |
$endpoint = $this->_discoverAndVerify($to_match->claimed_id, | $endpoint = $this->_discoverAndVerify($to_match->claimed_id, |
array($to_match)); | array($to_match)); |
if (Auth_OpenID::isFailure($endpoint)) { | if (Auth_OpenID::isFailure($endpoint)) { |
return $endpoint; | return $endpoint; |
} | } |
} | } |
} | } |
// The endpoint we return should have the claimed ID from the | // The endpoint we return should have the claimed ID from the |
// message we just verified, fragment and all. | // message we just verified, fragment and all. |
if ($endpoint->claimed_id != $to_match->claimed_id) { | if ($endpoint->claimed_id != $to_match->claimed_id) { |
$endpoint->claimed_id = $to_match->claimed_id; | $endpoint->claimed_id = $to_match->claimed_id; |
} | } |
return $endpoint; | return $endpoint; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _discoverAndVerify($claimed_id, $to_match_endpoints) | function _discoverAndVerify($claimed_id, $to_match_endpoints) |
{ | { |
// oidutil.log('Performing discovery on %s' % (claimed_id,)) | // oidutil.log('Performing discovery on %s' % (claimed_id,)) |
list($unused, $services) = call_user_func($this->discoverMethod, | list($unused, $services) = call_user_func($this->discoverMethod, |
$claimed_id, | $claimed_id, |
&$this->fetcher); | $this->fetcher); |
if (!$services) { | if (!$services) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
sprintf("No OpenID information found at %s", | sprintf("No OpenID information found at %s", |
$claimed_id)); | $claimed_id)); |
} | } |
return $this->_verifyDiscoveryServices($claimed_id, $services, | return $this->_verifyDiscoveryServices($claimed_id, $services, |
$to_match_endpoints); | $to_match_endpoints); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _verifyDiscoveryServices($claimed_id, | function _verifyDiscoveryServices($claimed_id, |
$services, $to_match_endpoints) | $services, $to_match_endpoints) |
{ | { |
// Search the services resulting from discovery to find one | // Search the services resulting from discovery to find one |
// that matches the information from the assertion | // that matches the information from the assertion |
foreach ($services as $endpoint) { | foreach ($services as $endpoint) { |
foreach ($to_match_endpoints as $to_match_endpoint) { | foreach ($to_match_endpoints as $to_match_endpoint) { |
$result = $this->_verifyDiscoverySingle($endpoint, | $result = $this->_verifyDiscoverySingle($endpoint, |
$to_match_endpoint); | $to_match_endpoint); |
if (!Auth_OpenID::isFailure($result)) { | if (!Auth_OpenID::isFailure($result)) { |
// It matches, so discover verification has | // It matches, so discover verification has |
// succeeded. Return this endpoint. | // succeeded. Return this endpoint. |
return $endpoint; | return $endpoint; |
} | } |
} | } |
} | } |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
sprintf('No matching endpoint found after discovering %s: %s', | sprintf('No matching endpoint found after discovering %s: %s', |
$claimed_id, $result->message)); | $claimed_id, $result->message)); |
} | } |
/** | /** |
* Extract the nonce from an OpenID 1 response. Return the nonce | * Extract the nonce from an OpenID 1 response. Return the nonce |
* from the BARE_NS since we independently check the return_to | * from the BARE_NS since we independently check the return_to |
* arguments are the same as those in the response message. | * arguments are the same as those in the response message. |
* | * |
* See the openid1_nonce_query_arg_name class variable | * See the openid1_nonce_query_arg_name class variable |
* | * |
* @returns $nonce The nonce as a string or null | * @returns $nonce The nonce as a string or null |
* | * |
* @access private | * @access private |
*/ | */ |
function _idResGetNonceOpenID1($message, $endpoint) | function _idResGetNonceOpenID1($message, $endpoint) |
{ | { |
return $message->getArg(Auth_OpenID_BARE_NS, | return $message->getArg(Auth_OpenID_BARE_NS, |
$this->openid1_nonce_query_arg_name); | $this->openid1_nonce_query_arg_name); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _idResCheckNonce($message, $endpoint) | function _idResCheckNonce($message, $endpoint) |
{ | { |
if ($message->isOpenID1()) { | if ($message->isOpenID1()) { |
// This indicates that the nonce was generated by the consumer | // This indicates that the nonce was generated by the consumer |
$nonce = $this->_idResGetNonceOpenID1($message, $endpoint); | $nonce = $this->_idResGetNonceOpenID1($message, $endpoint); |
$server_url = ''; | $server_url = ''; |
} else { | } else { |
$nonce = $message->getArg(Auth_OpenID_OPENID2_NS, | $nonce = $message->getArg(Auth_OpenID_OPENID2_NS, |
'response_nonce'); | 'response_nonce'); |
$server_url = $endpoint->server_url; | $server_url = $endpoint->server_url; |
} | } |
if ($nonce === null) { | if ($nonce === null) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
"Nonce missing from response"); | "Nonce missing from response"); |
} | } |
$parts = Auth_OpenID_splitNonce($nonce); | $parts = Auth_OpenID_splitNonce($nonce); |
if ($parts === null) { | if ($parts === null) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
"Malformed nonce in response"); | "Malformed nonce in response"); |
} | } |
list($timestamp, $salt) = $parts; | list($timestamp, $salt) = $parts; |
if (!$this->store->useNonce($server_url, $timestamp, $salt)) { | if (!$this->store->useNonce($server_url, $timestamp, $salt)) { |
return new Auth_OpenID_FailureResponse($endpoint, | return new Auth_OpenID_FailureResponse($endpoint, |
"Nonce already used or out of range"); | "Nonce already used or out of range"); |
} | } |
return null; | return null; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _idResCheckForFields($message) | function _idResCheckForFields($message) |
{ | { |
$basic_fields = array('return_to', 'assoc_handle', 'sig', 'signed'); | $basic_fields = array('return_to', 'assoc_handle', 'sig', 'signed'); |
$basic_sig_fields = array('return_to', 'identity'); | $basic_sig_fields = array('return_to', 'identity'); |
$require_fields = array( | $require_fields = array( |
Auth_OpenID_OPENID2_NS => array_merge($basic_fields, | Auth_OpenID_OPENID2_NS => array_merge($basic_fields, |
array('op_endpoint')), | array('op_endpoint')), |
Auth_OpenID_OPENID1_NS => array_merge($basic_fields, | Auth_OpenID_OPENID1_NS => array_merge($basic_fields, |
array('identity')) | array('identity')) |
); | ); |
$require_sigs = array( | $require_sigs = array( |
Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields, | Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields, |
array('response_nonce', | array('response_nonce', |
'claimed_id', | 'claimed_id', |
'assoc_handle', | 'assoc_handle', |
'op_endpoint')), | 'op_endpoint')), |
Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields, | Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields, |
array('nonce')) | array('nonce')) |
); | ); |
foreach ($require_fields[$message->getOpenIDNamespace()] as $field) { | foreach ($require_fields[$message->getOpenIDNamespace()] as $field) { |
if (!$message->hasKey(Auth_OpenID_OPENID_NS, $field)) { | if (!$message->hasKey(Auth_OpenID_OPENID_NS, $field)) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"Missing required field '".$field."'"); | "Missing required field '".$field."'"); |
} | } |
} | } |
$signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, | $signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, |
'signed', | 'signed', |
Auth_OpenID_NO_DEFAULT); | Auth_OpenID_NO_DEFAULT); |
if (Auth_OpenID::isFailure($signed_list_str)) { | if (Auth_OpenID::isFailure($signed_list_str)) { |
return $signed_list_str; | return $signed_list_str; |
} | } |
$signed_list = explode(',', $signed_list_str); | $signed_list = explode(',', $signed_list_str); |
foreach ($require_sigs[$message->getOpenIDNamespace()] as $field) { | foreach ($require_sigs[$message->getOpenIDNamespace()] as $field) { |
// Field is present and not in signed list | // Field is present and not in signed list |
if ($message->hasKey(Auth_OpenID_OPENID_NS, $field) && | if ($message->hasKey(Auth_OpenID_OPENID_NS, $field) && |
(!in_array($field, $signed_list))) { | (!in_array($field, $signed_list))) { |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"'".$field."' not signed"); | "'".$field."' not signed"); |
} | } |
} | } |
return null; | return null; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _checkAuth($message, $server_url) | function _checkAuth($message, $server_url) |
{ | { |
$request = $this->_createCheckAuthRequest($message); | $request = $this->_createCheckAuthRequest($message); |
if ($request === null) { | if ($request === null) { |
return false; | return false; |
} | } |
$resp_message = $this->_makeKVPost($request, $server_url); | $resp_message = $this->_makeKVPost($request, $server_url); |
if (($resp_message === null) || | if (($resp_message === null) || |
(is_a($resp_message, 'Auth_OpenID_ServerErrorContainer'))) { | (is_a($resp_message, 'Auth_OpenID_ServerErrorContainer'))) { |
return false; | return false; |
} | } |
return $this->_processCheckAuthResponse($resp_message, $server_url); | return $this->_processCheckAuthResponse($resp_message, $server_url); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _createCheckAuthRequest($message) | function _createCheckAuthRequest($message) |
{ | { |
$signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed'); | $signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed'); |
if ($signed) { | if ($signed) { |
foreach (explode(',', $signed) as $k) { | foreach (explode(',', $signed) as $k) { |
$value = $message->getAliasedArg($k); | $value = $message->getAliasedArg($k); |
if ($value === null) { | if ($value === null) { |
return null; | return null; |
} | } |
} | } |
} | } |
$ca_message = $message->copy(); | $ca_message = $message->copy(); |
$ca_message->setArg(Auth_OpenID_OPENID_NS, 'mode', | $ca_message->setArg(Auth_OpenID_OPENID_NS, 'mode', |
'check_authentication'); | 'check_authentication'); |
return $ca_message; | return $ca_message; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _processCheckAuthResponse($response, $server_url) | function _processCheckAuthResponse($response, $server_url) |
{ | { |
$is_valid = $response->getArg(Auth_OpenID_OPENID_NS, 'is_valid', | $is_valid = $response->getArg(Auth_OpenID_OPENID_NS, 'is_valid', |
'false'); | 'false'); |
$invalidate_handle = $response->getArg(Auth_OpenID_OPENID_NS, | $invalidate_handle = $response->getArg(Auth_OpenID_OPENID_NS, |
'invalidate_handle'); | 'invalidate_handle'); |
if ($invalidate_handle !== null) { | if ($invalidate_handle !== null) { |
$this->store->removeAssociation($server_url, | $this->store->removeAssociation($server_url, |
$invalidate_handle); | $invalidate_handle); |
} | } |
if ($is_valid == 'true') { | if ($is_valid == 'true') { |
return true; | return true; |
} | } |
return false; | return false; |
} | } |
/** | /** |
* Adapt a POST response to a Message. | * Adapt a POST response to a Message. |
* | * |
* @param $response Result of a POST to an OpenID endpoint. | * @param $response Result of a POST to an OpenID endpoint. |
* | * |
* @access private | * @access private |
*/ | */ |
static function _httpResponseToMessage($response, $server_url) | static function _httpResponseToMessage($response, $server_url) |
{ | { |
// Should this function be named Message.fromHTTPResponse instead? | // Should this function be named Message.fromHTTPResponse instead? |
$response_message = Auth_OpenID_Message::fromKVForm($response->body); | $response_message = Auth_OpenID_Message::fromKVForm($response->body); |
if ($response->status == 400) { | if ($response->status == 400) { |
return Auth_OpenID_ServerErrorContainer::fromMessage( | return Auth_OpenID_ServerErrorContainer::fromMessage( |
$response_message); | $response_message); |
} else if ($response->status != 200 and $response->status != 206) { | } else if ($response->status != 200 and $response->status != 206) { |
return null; | return null; |
} | } |
return $response_message; | return $response_message; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _makeKVPost($message, $server_url) | function _makeKVPost($message, $server_url) |
{ | { |
$body = $message->toURLEncoded(); | $body = $message->toURLEncoded(); |
$resp = $this->fetcher->post($server_url, $body); | $resp = $this->fetcher->post($server_url, $body); |
if ($resp === null) { | if ($resp === null) { |
return null; | return null; |
} | } |
return $this->_httpResponseToMessage($resp, $server_url); | return $this->_httpResponseToMessage($resp, $server_url); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _getAssociation($endpoint) | function _getAssociation($endpoint) |
{ | { |
if (!$this->_use_assocs) { | if (!$this->_use_assocs) { |
return null; | return null; |
} | } |
$assoc = $this->store->getAssociation($endpoint->server_url); | $assoc = $this->store->getAssociation($endpoint->server_url); |
if (($assoc === null) || | if (($assoc === null) || |
($assoc->getExpiresIn() <= 0)) { | ($assoc->getExpiresIn() <= 0)) { |
$assoc = $this->_negotiateAssociation($endpoint); | $assoc = $this->_negotiateAssociation($endpoint); |
if ($assoc !== null) { | if ($assoc !== null) { |
$this->store->storeAssociation($endpoint->server_url, | $this->store->storeAssociation($endpoint->server_url, |
$assoc); | $assoc); |
} | } |
} | } |
return $assoc; | return $assoc; |
} | } |
/** | /** |
* Handle ServerErrors resulting from association requests. | * Handle ServerErrors resulting from association requests. |
* | * |
* @return $result If server replied with an C{unsupported-type} | * @return $result If server replied with an C{unsupported-type} |
* error, return a tuple of supported C{association_type}, | * error, return a tuple of supported C{association_type}, |
* C{session_type}. Otherwise logs the error and returns null. | * C{session_type}. Otherwise logs the error and returns null. |
* | * |
* @access private | * @access private |
*/ | */ |
function _extractSupportedAssociationType($server_error, $endpoint, | function _extractSupportedAssociationType($server_error, $endpoint, |
$assoc_type) | $assoc_type) |
{ | { |
// Any error message whose code is not 'unsupported-type' | // Any error message whose code is not 'unsupported-type' |
// should be considered a total failure. | // should be considered a total failure. |
if (($server_error->error_code != 'unsupported-type') || | if (($server_error->error_code != 'unsupported-type') || |
($server_error->message->isOpenID1())) { | ($server_error->message->isOpenID1())) { |
return null; | return null; |
} | } |
// The server didn't like the association/session type that we | // The server didn't like the association/session type that we |
// sent, and it sent us back a message that might tell us how | // sent, and it sent us back a message that might tell us how |
// to handle it. | // to handle it. |
// Extract the session_type and assoc_type from the error | // Extract the session_type and assoc_type from the error |
// message | // message |
$assoc_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS, | $assoc_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS, |
'assoc_type'); | 'assoc_type'); |
$session_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS, | $session_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS, |
'session_type'); | 'session_type'); |
if (($assoc_type === null) || ($session_type === null)) { | if (($assoc_type === null) || ($session_type === null)) { |
return null; | return null; |
} else if (!$this->negotiator->isAllowed($assoc_type, | } else if (!$this->negotiator->isAllowed($assoc_type, |
$session_type)) { | $session_type)) { |
return null; | return null; |
} else { | } else { |
return array($assoc_type, $session_type); | return array($assoc_type, $session_type); |
} | } |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _negotiateAssociation($endpoint) | function _negotiateAssociation($endpoint) |
{ | { |
// Get our preferred session/association type from the negotiatior. | // Get our preferred session/association type from the negotiatior. |
list($assoc_type, $session_type) = $this->negotiator->getAllowedType(); | list($assoc_type, $session_type) = $this->negotiator->getAllowedType(); |
$assoc = $this->_requestAssociation( | $assoc = $this->_requestAssociation( |
$endpoint, $assoc_type, $session_type); | $endpoint, $assoc_type, $session_type); |
if (Auth_OpenID::isFailure($assoc)) { | if (Auth_OpenID::isFailure($assoc)) { |
return null; | return null; |
} | } |
if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) { | if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) { |
$why = $assoc; | $why = $assoc; |
$supportedTypes = $this->_extractSupportedAssociationType( | $supportedTypes = $this->_extractSupportedAssociationType( |
$why, $endpoint, $assoc_type); | $why, $endpoint, $assoc_type); |
if ($supportedTypes !== null) { | if ($supportedTypes !== null) { |
list($assoc_type, $session_type) = $supportedTypes; | list($assoc_type, $session_type) = $supportedTypes; |
// Attempt to create an association from the assoc_type | // Attempt to create an association from the assoc_type |
// and session_type that the server told us it | // and session_type that the server told us it |
// supported. | // supported. |
$assoc = $this->_requestAssociation( | $assoc = $this->_requestAssociation( |
$endpoint, $assoc_type, $session_type); | $endpoint, $assoc_type, $session_type); |
if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) { | if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) { |
// Do not keep trying, since it rejected the | // Do not keep trying, since it rejected the |
// association type that it told us to use. | // association type that it told us to use. |
// oidutil.log('Server %s refused its suggested association | // oidutil.log('Server %s refused its suggested association |
// 'type: session_type=%s, assoc_type=%s' | // 'type: session_type=%s, assoc_type=%s' |
// % (endpoint.server_url, session_type, | // % (endpoint.server_url, session_type, |
// assoc_type)) | // assoc_type)) |
return null; | return null; |
} else { | } else { |
return $assoc; | return $assoc; |
} | } |
} else { | } else { |
return null; | return null; |
} | } |
} else { | } else { |
return $assoc; | return $assoc; |
} | } |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _requestAssociation($endpoint, $assoc_type, $session_type) | function _requestAssociation($endpoint, $assoc_type, $session_type) |
{ | { |
list($assoc_session, $args) = $this->_createAssociateRequest( | list($assoc_session, $args) = $this->_createAssociateRequest( |
$endpoint, $assoc_type, $session_type); | $endpoint, $assoc_type, $session_type); |
$response_message = $this->_makeKVPost($args, $endpoint->server_url); | $response_message = $this->_makeKVPost($args, $endpoint->server_url); |
if ($response_message === null) { | if ($response_message === null) { |
// oidutil.log('openid.associate request failed: %s' % (why[0],)) | // oidutil.log('openid.associate request failed: %s' % (why[0],)) |
return null; | return null; |
} else if (is_a($response_message, | } else if (is_a($response_message, |
'Auth_OpenID_ServerErrorContainer')) { | 'Auth_OpenID_ServerErrorContainer')) { |
return $response_message; | return $response_message; |
} | } |
return $this->_extractAssociation($response_message, $assoc_session); | return $this->_extractAssociation($response_message, $assoc_session); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _extractAssociation($assoc_response, $assoc_session) | function _extractAssociation($assoc_response, $assoc_session) |
{ | { |
// Extract the common fields from the response, raising an | // Extract the common fields from the response, raising an |
// exception if they are not found | // exception if they are not found |
$assoc_type = $assoc_response->getArg( | $assoc_type = $assoc_response->getArg( |
Auth_OpenID_OPENID_NS, 'assoc_type', | Auth_OpenID_OPENID_NS, 'assoc_type', |
Auth_OpenID_NO_DEFAULT); | Auth_OpenID_NO_DEFAULT); |
if (Auth_OpenID::isFailure($assoc_type)) { | if (Auth_OpenID::isFailure($assoc_type)) { |
return $assoc_type; | return $assoc_type; |
} | } |
$assoc_handle = $assoc_response->getArg( | $assoc_handle = $assoc_response->getArg( |
Auth_OpenID_OPENID_NS, 'assoc_handle', | Auth_OpenID_OPENID_NS, 'assoc_handle', |
Auth_OpenID_NO_DEFAULT); | Auth_OpenID_NO_DEFAULT); |
if (Auth_OpenID::isFailure($assoc_handle)) { | if (Auth_OpenID::isFailure($assoc_handle)) { |
return $assoc_handle; | return $assoc_handle; |
} | } |
// expires_in is a base-10 string. The Python parsing will | // expires_in is a base-10 string. The Python parsing will |
// accept literals that have whitespace around them and will | // accept literals that have whitespace around them and will |
// accept negative values. Neither of these are really in-spec, | // accept negative values. Neither of these are really in-spec, |
// but we think it's OK to accept them. | // but we think it's OK to accept them. |
$expires_in_str = $assoc_response->getArg( | $expires_in_str = $assoc_response->getArg( |
Auth_OpenID_OPENID_NS, 'expires_in', | Auth_OpenID_OPENID_NS, 'expires_in', |
Auth_OpenID_NO_DEFAULT); | Auth_OpenID_NO_DEFAULT); |
if (Auth_OpenID::isFailure($expires_in_str)) { | if (Auth_OpenID::isFailure($expires_in_str)) { |
return $expires_in_str; | return $expires_in_str; |
} | } |
$expires_in = Auth_OpenID::intval($expires_in_str); | $expires_in = Auth_OpenID::intval($expires_in_str); |
if ($expires_in === false) { | if ($expires_in === false) { |
$err = sprintf("Could not parse expires_in from association ". | $err = sprintf("Could not parse expires_in from association ". |
"response %s", print_r($assoc_response, true)); | "response %s", print_r($assoc_response, true)); |
return new Auth_OpenID_FailureResponse(null, $err); | return new Auth_OpenID_FailureResponse(null, $err); |
} | } |
// OpenID 1 has funny association session behaviour. | // OpenID 1 has funny association session behaviour. |
if ($assoc_response->isOpenID1()) { | if ($assoc_response->isOpenID1()) { |
$session_type = $this->_getOpenID1SessionType($assoc_response); | $session_type = $this->_getOpenID1SessionType($assoc_response); |
} else { | } else { |
$session_type = $assoc_response->getArg( | $session_type = $assoc_response->getArg( |
Auth_OpenID_OPENID2_NS, 'session_type', | Auth_OpenID_OPENID2_NS, 'session_type', |
Auth_OpenID_NO_DEFAULT); | Auth_OpenID_NO_DEFAULT); |
if (Auth_OpenID::isFailure($session_type)) { | if (Auth_OpenID::isFailure($session_type)) { |
return $session_type; | return $session_type; |
} | } |
} | } |
// Session type mismatch | // Session type mismatch |
if ($assoc_session->session_type != $session_type) { | if ($assoc_session->session_type != $session_type) { |
if ($assoc_response->isOpenID1() && | if ($assoc_response->isOpenID1() && |
($session_type == 'no-encryption')) { | ($session_type == 'no-encryption')) { |
// In OpenID 1, any association request can result in | // In OpenID 1, any association request can result in |
// a 'no-encryption' association response. Setting | // a 'no-encryption' association response. Setting |
// assoc_session to a new no-encryption session should | // assoc_session to a new no-encryption session should |
// make the rest of this function work properly for | // make the rest of this function work properly for |
// that case. | // that case. |
$assoc_session = new Auth_OpenID_PlainTextConsumerSession(); | $assoc_session = new Auth_OpenID_PlainTextConsumerSession(); |
} else { | } else { |
// Any other mismatch, regardless of protocol version | // Any other mismatch, regardless of protocol version |
// results in the failure of the association session | // results in the failure of the association session |
// altogether. | // altogether. |
return null; | return null; |
} | } |
} | } |
// Make sure assoc_type is valid for session_type | // Make sure assoc_type is valid for session_type |
if (!in_array($assoc_type, $assoc_session->allowed_assoc_types)) { | if (!in_array($assoc_type, $assoc_session->allowed_assoc_types)) { |
return null; | return null; |
} | } |
// Delegate to the association session to extract the secret | // Delegate to the association session to extract the secret |
// from the response, however is appropriate for that session | // from the response, however is appropriate for that session |
// type. | // type. |
$secret = $assoc_session->extractSecret($assoc_response); | $secret = $assoc_session->extractSecret($assoc_response); |
if ($secret === null) { | if ($secret === null) { |
return null; | return null; |
} | } |
return Auth_OpenID_Association::fromExpiresIn( | return Auth_OpenID_Association::fromExpiresIn( |
$expires_in, $assoc_handle, $secret, $assoc_type); | $expires_in, $assoc_handle, $secret, $assoc_type); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _createAssociateRequest($endpoint, $assoc_type, $session_type) | function _createAssociateRequest($endpoint, $assoc_type, $session_type) |
{ | { |
if (array_key_exists($session_type, $this->session_types)) { | if (array_key_exists($session_type, $this->session_types)) { |
$session_type_class = $this->session_types[$session_type]; | $session_type_class = $this->session_types[$session_type]; |
if (is_callable($session_type_class)) { | if (is_callable($session_type_class)) { |
$assoc_session = $session_type_class(); | $assoc_session = $session_type_class(); |
} else { | } else { |
$assoc_session = new $session_type_class(); | $assoc_session = new $session_type_class(); |
} | } |
} else { | } else { |
return null; | return null; |
} | } |
$args = array( | $args = array( |
'mode' => 'associate', | 'mode' => 'associate', |
'assoc_type' => $assoc_type); | 'assoc_type' => $assoc_type); |
if (!$endpoint->compatibilityMode()) { | if (!$endpoint->compatibilityMode()) { |
$args['ns'] = Auth_OpenID_OPENID2_NS; | $args['ns'] = Auth_OpenID_OPENID2_NS; |
} | } |
// Leave out the session type if we're in compatibility mode | // Leave out the session type if we're in compatibility mode |
// *and* it's no-encryption. | // *and* it's no-encryption. |
if ((!$endpoint->compatibilityMode()) || | if ((!$endpoint->compatibilityMode()) || |
($assoc_session->session_type != 'no-encryption')) { | ($assoc_session->session_type != 'no-encryption')) { |
$args['session_type'] = $assoc_session->session_type; | $args['session_type'] = $assoc_session->session_type; |
} | } |
$args = array_merge($args, $assoc_session->getRequest()); | $args = array_merge($args, $assoc_session->getRequest()); |
$message = Auth_OpenID_Message::fromOpenIDArgs($args); | $message = Auth_OpenID_Message::fromOpenIDArgs($args); |
return array($assoc_session, $message); | return array($assoc_session, $message); |
} | } |
/** | /** |
* Given an association response message, extract the OpenID 1.X | * Given an association response message, extract the OpenID 1.X |
* session type. | * session type. |
* | * |
* This function mostly takes care of the 'no-encryption' default | * This function mostly takes care of the 'no-encryption' default |
* behavior in OpenID 1. | * behavior in OpenID 1. |
* | * |
* If the association type is plain-text, this function will | * If the association type is plain-text, this function will |
* return 'no-encryption' | * return 'no-encryption' |
* | * |
* @access private | * @access private |
* @return $typ The association type for this message | * @return $typ The association type for this message |
*/ | */ |
function _getOpenID1SessionType($assoc_response) | function _getOpenID1SessionType($assoc_response) |
{ | { |
// If it's an OpenID 1 message, allow session_type to default | // If it's an OpenID 1 message, allow session_type to default |
// to None (which signifies "no-encryption") | // to None (which signifies "no-encryption") |
$session_type = $assoc_response->getArg(Auth_OpenID_OPENID1_NS, | $session_type = $assoc_response->getArg(Auth_OpenID_OPENID1_NS, |
'session_type'); | 'session_type'); |
// Handle the differences between no-encryption association | // Handle the differences between no-encryption association |
// respones in OpenID 1 and 2: | // respones in OpenID 1 and 2: |
// no-encryption is not really a valid session type for OpenID | // no-encryption is not really a valid session type for OpenID |
// 1, but we'll accept it anyway, while issuing a warning. | // 1, but we'll accept it anyway, while issuing a warning. |
if ($session_type == 'no-encryption') { | if ($session_type == 'no-encryption') { |
// oidutil.log('WARNING: OpenID server sent "no-encryption"' | // oidutil.log('WARNING: OpenID server sent "no-encryption"' |
// 'for OpenID 1.X') | // 'for OpenID 1.X') |
} else if (($session_type == '') || ($session_type === null)) { | } else if (($session_type == '') || ($session_type === null)) { |
// Missing or empty session type is the way to flag a | // Missing or empty session type is the way to flag a |
// 'no-encryption' response. Change the session type to | // 'no-encryption' response. Change the session type to |
// 'no-encryption' so that it can be handled in the same | // 'no-encryption' so that it can be handled in the same |
// way as OpenID 2 'no-encryption' respones. | // way as OpenID 2 'no-encryption' respones. |
$session_type = 'no-encryption'; | $session_type = 'no-encryption'; |
} | } |
return $session_type; | return $session_type; |
} | } |
} | } |
/** | /** |
* This class represents an authentication request from a consumer to | * This class represents an authentication request from a consumer to |
* an OpenID server. | * an OpenID server. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_AuthRequest { | class Auth_OpenID_AuthRequest { |
/** | /** |
* Initialize an authentication request with the specified token, | * Initialize an authentication request with the specified token, |
* association, and endpoint. | * association, and endpoint. |
* | * |
* Users of this library should not create instances of this | * Users of this library should not create instances of this |
* class. Instances of this class are created by the library when | * class. Instances of this class are created by the library when |
* needed. | * needed. |
*/ | */ |
function Auth_OpenID_AuthRequest($endpoint, $assoc) | function Auth_OpenID_AuthRequest($endpoint, $assoc) |
{ | { |
$this->assoc = $assoc; | $this->assoc = $assoc; |
$this->endpoint = $endpoint; | $this->endpoint = $endpoint; |
$this->return_to_args = array(); | $this->return_to_args = array(); |
$this->message = new Auth_OpenID_Message( | $this->message = new Auth_OpenID_Message( |
$endpoint->preferredNamespace()); | $endpoint->preferredNamespace()); |
$this->_anonymous = false; | $this->_anonymous = false; |
} | } |
/** | /** |
* Add an extension to this checkid request. | * Add an extension to this checkid request. |
* | * |
* $extension_request: An object that implements the extension | * $extension_request: An object that implements the extension |
* request interface for adding arguments to an OpenID message. | * request interface for adding arguments to an OpenID message. |
*/ | */ |
function addExtension($extension_request) | function addExtension($extension_request) |
{ | { |
$extension_request->toMessage($this->message); | $extension_request->toMessage($this->message); |
} | } |
/** | /** |
* Add an extension argument to this OpenID authentication | * Add an extension argument to this OpenID authentication |
* request. | * request. |
* | * |
* Use caution when adding arguments, because they will be | * Use caution when adding arguments, because they will be |
* URL-escaped and appended to the redirect URL, which can easily | * URL-escaped and appended to the redirect URL, which can easily |
* get quite long. | * get quite long. |
* | * |
* @param string $namespace The namespace for the extension. For | * @param string $namespace The namespace for the extension. For |
* example, the simple registration extension uses the namespace | * example, the simple registration extension uses the namespace |
* 'sreg'. | * 'sreg'. |
* | * |
* @param string $key The key within the extension namespace. For | * @param string $key The key within the extension namespace. For |
* example, the nickname field in the simple registration | * example, the nickname field in the simple registration |
* extension's key is 'nickname'. | * extension's key is 'nickname'. |
* | * |
* @param string $value The value to provide to the server for | * @param string $value The value to provide to the server for |
* this argument. | * this argument. |
*/ | */ |
function addExtensionArg($namespace, $key, $value) | function addExtensionArg($namespace, $key, $value) |
{ | { |
return $this->message->setArg($namespace, $key, $value); | return $this->message->setArg($namespace, $key, $value); |
} | } |
/** | /** |
* Set whether this request should be made anonymously. If a | * Set whether this request should be made anonymously. If a |
* request is anonymous, the identifier will not be sent in the | * request is anonymous, the identifier will not be sent in the |
* request. This is only useful if you are making another kind of | * request. This is only useful if you are making another kind of |
* request with an extension in this request. | * request with an extension in this request. |
* | * |
* Anonymous requests are not allowed when the request is made | * Anonymous requests are not allowed when the request is made |
* with OpenID 1. | * with OpenID 1. |
*/ | */ |
function setAnonymous($is_anonymous) | function setAnonymous($is_anonymous) |
{ | { |
if ($is_anonymous && $this->message->isOpenID1()) { | if ($is_anonymous && $this->message->isOpenID1()) { |
return false; | return false; |
} else { | } else { |
$this->_anonymous = $is_anonymous; | $this->_anonymous = $is_anonymous; |
return true; | return true; |
} | } |
} | } |
/** | /** |
* Produce a {@link Auth_OpenID_Message} representing this | * Produce a {@link Auth_OpenID_Message} representing this |
* request. | * request. |
* | * |
* @param string $realm The URL (or URL pattern) that identifies | * @param string $realm The URL (or URL pattern) that identifies |
* your web site to the user when she is authorizing it. | * your web site to the user when she is authorizing it. |
* | * |
* @param string $return_to The URL that the OpenID provider will | * @param string $return_to The URL that the OpenID provider will |
* send the user back to after attempting to verify her identity. | * send the user back to after attempting to verify her identity. |
* | * |
* Not specifying a return_to URL means that the user will not be | * Not specifying a return_to URL means that the user will not be |
* returned to the site issuing the request upon its completion. | * returned to the site issuing the request upon its completion. |
* | * |
* @param bool $immediate If true, the OpenID provider is to send | * @param bool $immediate If true, the OpenID provider is to send |
* back a response immediately, useful for behind-the-scenes | * back a response immediately, useful for behind-the-scenes |
* authentication attempts. Otherwise the OpenID provider may | * authentication attempts. Otherwise the OpenID provider may |
* engage the user before providing a response. This is the | * engage the user before providing a response. This is the |
* default case, as the user may need to provide credentials or | * default case, as the user may need to provide credentials or |
* approve the request before a positive response can be sent. | * approve the request before a positive response can be sent. |
*/ | */ |
function getMessage($realm, $return_to=null, $immediate=false) | function getMessage($realm, $return_to=null, $immediate=false) |
{ | { |
if ($return_to) { | if ($return_to) { |
$return_to = Auth_OpenID::appendArgs($return_to, | $return_to = Auth_OpenID::appendArgs($return_to, |
$this->return_to_args); | $this->return_to_args); |
} else if ($immediate) { | } else if ($immediate) { |
// raise ValueError( | // raise ValueError( |
// '"return_to" is mandatory when | // '"return_to" is mandatory when |
//using "checkid_immediate"') | //using "checkid_immediate"') |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"'return_to' is mandatory when using checkid_immediate"); | "'return_to' is mandatory when using checkid_immediate"); |
} else if ($this->message->isOpenID1()) { | } else if ($this->message->isOpenID1()) { |
// raise ValueError('"return_to" is | // raise ValueError('"return_to" is |
// mandatory for OpenID 1 requests') | // mandatory for OpenID 1 requests') |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"'return_to' is mandatory for OpenID 1 requests"); | "'return_to' is mandatory for OpenID 1 requests"); |
} else if ($this->return_to_args) { | } else if ($this->return_to_args) { |
// raise ValueError('extra "return_to" arguments | // raise ValueError('extra "return_to" arguments |
// were specified, but no return_to was specified') | // were specified, but no return_to was specified') |
return new Auth_OpenID_FailureResponse(null, | return new Auth_OpenID_FailureResponse(null, |
"extra 'return_to' arguments where specified, " . | "extra 'return_to' arguments where specified, " . |
"but no return_to was specified"); | "but no return_to was specified"); |
} | } |
if ($immediate) { | if ($immediate) { |
$mode = 'checkid_immediate'; | $mode = 'checkid_immediate'; |
} else { | } else { |
$mode = 'checkid_setup'; | $mode = 'checkid_setup'; |
} | } |
$message = $this->message->copy(); | $message = $this->message->copy(); |
if ($message->isOpenID1()) { | if ($message->isOpenID1()) { |
$realm_key = 'trust_root'; | $realm_key = 'trust_root'; |
} else { | } else { |
$realm_key = 'realm'; | $realm_key = 'realm'; |
} | } |
$message->updateArgs(Auth_OpenID_OPENID_NS, | $message->updateArgs(Auth_OpenID_OPENID_NS, |
array( | array( |
$realm_key => $realm, | $realm_key => $realm, |
'mode' => $mode, | 'mode' => $mode, |
'return_to' => $return_to)); | 'return_to' => $return_to)); |
if (!$this->_anonymous) { | if (!$this->_anonymous) { |
if ($this->endpoint->isOPIdentifier()) { | if ($this->endpoint->isOPIdentifier()) { |
// This will never happen when we're in compatibility | // This will never happen when we're in compatibility |
// mode, as long as isOPIdentifier() returns False | // mode, as long as isOPIdentifier() returns False |
// whenever preferredNamespace() returns OPENID1_NS. | // whenever preferredNamespace() returns OPENID1_NS. |
$claimed_id = $request_identity = | $claimed_id = $request_identity = |
Auth_OpenID_IDENTIFIER_SELECT; | Auth_OpenID_IDENTIFIER_SELECT; |
} else { | } else { |
$request_identity = $this->endpoint->getLocalID(); | $request_identity = $this->endpoint->getLocalID(); |
$claimed_id = $this->endpoint->claimed_id; | $claimed_id = $this->endpoint->claimed_id; |
} | } |
// This is true for both OpenID 1 and 2 | // This is true for both OpenID 1 and 2 |
$message->setArg(Auth_OpenID_OPENID_NS, 'identity', | $message->setArg(Auth_OpenID_OPENID_NS, 'identity', |
$request_identity); | $request_identity); |
if ($message->isOpenID2()) { | if ($message->isOpenID2()) { |
$message->setArg(Auth_OpenID_OPENID2_NS, 'claimed_id', | $message->setArg(Auth_OpenID_OPENID2_NS, 'claimed_id', |
$claimed_id); | $claimed_id); |
} | } |
} | } |
if ($this->assoc) { | if ($this->assoc) { |
$message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle', | $message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle', |
$this->assoc->handle); | $this->assoc->handle); |
} | } |
return $message; | return $message; |
} | } |
function redirectURL($realm, $return_to = null, | function redirectURL($realm, $return_to = null, |
$immediate = false) | $immediate = false) |
{ | { |
$message = $this->getMessage($realm, $return_to, $immediate); | $message = $this->getMessage($realm, $return_to, $immediate); |
if (Auth_OpenID::isFailure($message)) { | if (Auth_OpenID::isFailure($message)) { |
return $message; | return $message; |
} | } |
return $message->toURL($this->endpoint->server_url); | return $message->toURL($this->endpoint->server_url); |
} | } |
/** | /** |
* Get html for a form to submit this request to the IDP. | * Get html for a form to submit this request to the IDP. |
* | * |
* form_tag_attrs: An array of attributes to be added to the form | * form_tag_attrs: An array of attributes to be added to the form |
* tag. 'accept-charset' and 'enctype' have defaults that can be | * tag. 'accept-charset' and 'enctype' have defaults that can be |
* overridden. If a value is supplied for 'action' or 'method', it | * overridden. If a value is supplied for 'action' or 'method', it |
* will be replaced. | * will be replaced. |
*/ | */ |
function formMarkup($realm, $return_to=null, $immediate=false, | function formMarkup($realm, $return_to=null, $immediate=false, |
$form_tag_attrs=null) | $form_tag_attrs=null) |
{ | { |
$message = $this->getMessage($realm, $return_to, $immediate); | $message = $this->getMessage($realm, $return_to, $immediate); |
if (Auth_OpenID::isFailure($message)) { | if (Auth_OpenID::isFailure($message)) { |
return $message; | return $message; |
} | } |
return $message->toFormMarkup($this->endpoint->server_url, | return $message->toFormMarkup($this->endpoint->server_url, |
$form_tag_attrs); | $form_tag_attrs); |
} | } |
/** | /** |
* Get a complete html document that will autosubmit the request | * Get a complete html document that will autosubmit the request |
* to the IDP. | * to the IDP. |
* | * |
* Wraps formMarkup. See the documentation for that function. | * Wraps formMarkup. See the documentation for that function. |
*/ | */ |
function htmlMarkup($realm, $return_to=null, $immediate=false, | function htmlMarkup($realm, $return_to=null, $immediate=false, |
$form_tag_attrs=null) | $form_tag_attrs=null) |
{ | { |
$form = $this->formMarkup($realm, $return_to, $immediate, | $form = $this->formMarkup($realm, $return_to, $immediate, |
$form_tag_attrs); | $form_tag_attrs); |
if (Auth_OpenID::isFailure($form)) { | if (Auth_OpenID::isFailure($form)) { |
return $form; | return $form; |
} | } |
return Auth_OpenID::autoSubmitHTML($form); | return Auth_OpenID::autoSubmitHTML($form); |
} | } |
function shouldSendRedirect() | function shouldSendRedirect() |
{ | { |
return $this->endpoint->compatibilityMode(); | return $this->endpoint->compatibilityMode(); |
} | } |
} | } |
/** | /** |
* The base class for responses from the Auth_OpenID_Consumer. | * The base class for responses from the Auth_OpenID_Consumer. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_ConsumerResponse { | class Auth_OpenID_ConsumerResponse { |
var $status = null; | var $status = null; |
function setEndpoint($endpoint) | function setEndpoint($endpoint) |
{ | { |
$this->endpoint = $endpoint; | $this->endpoint = $endpoint; |
if ($endpoint === null) { | if ($endpoint === null) { |
$this->identity_url = null; | $this->identity_url = null; |
} else { | } else { |
$this->identity_url = $endpoint->claimed_id; | $this->identity_url = $endpoint->claimed_id; |
} | } |
} | } |
/** | /** |
* Return the display identifier for this response. | * Return the display identifier for this response. |
* | * |
* The display identifier is related to the Claimed Identifier, but the | * The display identifier is related to the Claimed Identifier, but the |
* two are not always identical. The display identifier is something the | * two are not always identical. The display identifier is something the |
* user should recognize as what they entered, whereas the response's | * user should recognize as what they entered, whereas the response's |
* claimed identifier (in the identity_url attribute) may have extra | * claimed identifier (in the identity_url attribute) may have extra |
* information for better persistence. | * information for better persistence. |
* | * |
* URLs will be stripped of their fragments for display. XRIs will | * URLs will be stripped of their fragments for display. XRIs will |
* display the human-readable identifier (i-name) instead of the | * display the human-readable identifier (i-name) instead of the |
* persistent identifier (i-number). | * persistent identifier (i-number). |
* | * |
* Use the display identifier in your user interface. Use | * Use the display identifier in your user interface. Use |
* identity_url for querying your database or authorization server. | * identity_url for querying your database or authorization server. |
* | * |
*/ | */ |
function getDisplayIdentifier() | function getDisplayIdentifier() |
{ | { |
if ($this->endpoint !== null) { | if ($this->endpoint !== null) { |
return $this->endpoint->getDisplayIdentifier(); | return $this->endpoint->getDisplayIdentifier(); |
} | } |
return null; | return null; |
} | } |
} | } |
/** | /** |
* A response with a status of Auth_OpenID_SUCCESS. Indicates that | * A response with a status of Auth_OpenID_SUCCESS. Indicates that |
* this request is a successful acknowledgement from the OpenID server | * this request is a successful acknowledgement from the OpenID server |
* that the supplied URL is, indeed controlled by the requesting | * that the supplied URL is, indeed controlled by the requesting |
* agent. This has three relevant attributes: | * agent. This has three relevant attributes: |
* | * |
* claimed_id - The identity URL that has been authenticated | * claimed_id - The identity URL that has been authenticated |
* | * |
* signed_args - The arguments in the server's response that were | * signed_args - The arguments in the server's response that were |
* signed and verified. | * signed and verified. |
* | * |
* status - Auth_OpenID_SUCCESS. | * status - Auth_OpenID_SUCCESS. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_SuccessResponse extends Auth_OpenID_ConsumerResponse { | class Auth_OpenID_SuccessResponse extends Auth_OpenID_ConsumerResponse { |
var $status = Auth_OpenID_SUCCESS; | var $status = Auth_OpenID_SUCCESS; |
/** | /** |
* @access private | * @access private |
*/ | */ |
function Auth_OpenID_SuccessResponse($endpoint, $message, $signed_args=null) | function Auth_OpenID_SuccessResponse($endpoint, $message, $signed_args=null) |
{ | { |
$this->endpoint = $endpoint; | $this->endpoint = $endpoint; |
$this->identity_url = $endpoint->claimed_id; | $this->identity_url = $endpoint->claimed_id; |
$this->signed_args = $signed_args; | $this->signed_args = $signed_args; |
$this->message = $message; | $this->message = $message; |
if ($this->signed_args === null) { | if ($this->signed_args === null) { |
$this->signed_args = array(); | $this->signed_args = array(); |
} | } |
} | } |
/** | /** |
* Extract signed extension data from the server's response. | * Extract signed extension data from the server's response. |
* | * |
* @param string $prefix The extension namespace from which to | * @param string $prefix The extension namespace from which to |
* extract the extension data. | * extract the extension data. |
*/ | */ |
function extensionResponse($namespace_uri, $require_signed) | function extensionResponse($namespace_uri, $require_signed) |
{ | { |
if ($require_signed) { | if ($require_signed) { |
return $this->getSignedNS($namespace_uri); | return $this->getSignedNS($namespace_uri); |
} else { | } else { |
return $this->message->getArgs($namespace_uri); | return $this->message->getArgs($namespace_uri); |
} | } |
} | } |
function isOpenID1() | function isOpenID1() |
{ | { |
return $this->message->isOpenID1(); | return $this->message->isOpenID1(); |
} | } |
function isSigned($ns_uri, $ns_key) | function isSigned($ns_uri, $ns_key) |
{ | { |
// Return whether a particular key is signed, regardless of | // Return whether a particular key is signed, regardless of |
// its namespace alias | // its namespace alias |
return in_array($this->message->getKey($ns_uri, $ns_key), | return in_array($this->message->getKey($ns_uri, $ns_key), |
$this->signed_args); | $this->signed_args); |
} | } |
function getSigned($ns_uri, $ns_key, $default = null) | function getSigned($ns_uri, $ns_key, $default = null) |
{ | { |
// Return the specified signed field if available, otherwise | // Return the specified signed field if available, otherwise |
// return default | // return default |
if ($this->isSigned($ns_uri, $ns_key)) { | if ($this->isSigned($ns_uri, $ns_key)) { |
return $this->message->getArg($ns_uri, $ns_key, $default); | return $this->message->getArg($ns_uri, $ns_key, $default); |
} else { | } else { |
return $default; | return $default; |
} | } |
} | } |
function getSignedNS($ns_uri) | function getSignedNS($ns_uri) |
{ | { |
$args = array(); | $args = array(); |
$msg_args = $this->message->getArgs($ns_uri); | $msg_args = $this->message->getArgs($ns_uri); |
if (Auth_OpenID::isFailure($msg_args)) { | if (Auth_OpenID::isFailure($msg_args)) { |
return null; | return null; |
} | } |
foreach ($msg_args as $key => $value) { | foreach ($msg_args as $key => $value) { |
if (!$this->isSigned($ns_uri, $key)) { | if (!$this->isSigned($ns_uri, $key)) { |
unset($msg_args[$key]); | unset($msg_args[$key]); |
} | } |
} | } |
return $msg_args; | return $msg_args; |
} | } |
/** | /** |
* Get the openid.return_to argument from this response. | * Get the openid.return_to argument from this response. |
* | * |
* This is useful for verifying that this request was initiated by | * This is useful for verifying that this request was initiated by |
* this consumer. | * this consumer. |
* | * |
* @return string $return_to The return_to URL supplied to the | * @return string $return_to The return_to URL supplied to the |
* server on the initial request, or null if the response did not | * server on the initial request, or null if the response did not |
* contain an 'openid.return_to' argument. | * contain an 'openid.return_to' argument. |
*/ | */ |
function getReturnTo() | function getReturnTo() |
{ | { |
return $this->getSigned(Auth_OpenID_OPENID_NS, 'return_to'); | return $this->getSigned(Auth_OpenID_OPENID_NS, 'return_to'); |
} | } |
} | } |
/** | /** |
* A response with a status of Auth_OpenID_FAILURE. Indicates that the | * A response with a status of Auth_OpenID_FAILURE. Indicates that the |
* OpenID protocol has failed. This could be locally or remotely | * OpenID protocol has failed. This could be locally or remotely |
* triggered. This has three relevant attributes: | * triggered. This has three relevant attributes: |
* | * |
* claimed_id - The identity URL for which authentication was | * claimed_id - The identity URL for which authentication was |
* attempted, if it can be determined. Otherwise, null. | * attempted, if it can be determined. Otherwise, null. |
* | * |
* message - A message indicating why the request failed, if one is | * message - A message indicating why the request failed, if one is |
* supplied. Otherwise, null. | * supplied. Otherwise, null. |
* | * |
* status - Auth_OpenID_FAILURE. | * status - Auth_OpenID_FAILURE. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_FailureResponse extends Auth_OpenID_ConsumerResponse { | class Auth_OpenID_FailureResponse extends Auth_OpenID_ConsumerResponse { |
var $status = Auth_OpenID_FAILURE; | var $status = Auth_OpenID_FAILURE; |
function Auth_OpenID_FailureResponse($endpoint, $message = null, | function Auth_OpenID_FailureResponse($endpoint, $message = null, |
$contact = null, $reference = null) | $contact = null, $reference = null) |
{ | { |
$this->setEndpoint($endpoint); | $this->setEndpoint($endpoint); |
$this->message = $message; | $this->message = $message; |
$this->contact = $contact; | $this->contact = $contact; |
$this->reference = $reference; | $this->reference = $reference; |
} | } |
} | } |
/** | /** |
* A specific, internal failure used to detect type URI mismatch. | * A specific, internal failure used to detect type URI mismatch. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_TypeURIMismatch extends Auth_OpenID_FailureResponse { | class Auth_OpenID_TypeURIMismatch extends Auth_OpenID_FailureResponse { |
} | } |
/** | /** |
* Exception that is raised when the server returns a 400 response | * Exception that is raised when the server returns a 400 response |
* code to a direct request. | * code to a direct request. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_ServerErrorContainer { | class Auth_OpenID_ServerErrorContainer { |
function Auth_OpenID_ServerErrorContainer($error_text, | function Auth_OpenID_ServerErrorContainer($error_text, |
$error_code, | $error_code, |
$message) | $message) |
{ | { |
$this->error_text = $error_text; | $this->error_text = $error_text; |
$this->error_code = $error_code; | $this->error_code = $error_code; |
$this->message = $message; | $this->message = $message; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
static function fromMessage($message) | static function fromMessage($message) |
{ | { |
$error_text = $message->getArg( | $error_text = $message->getArg( |
Auth_OpenID_OPENID_NS, 'error', '<no error message supplied>'); | Auth_OpenID_OPENID_NS, 'error', '<no error message supplied>'); |
$error_code = $message->getArg(Auth_OpenID_OPENID_NS, 'error_code'); | $error_code = $message->getArg(Auth_OpenID_OPENID_NS, 'error_code'); |
return new Auth_OpenID_ServerErrorContainer($error_text, | return new Auth_OpenID_ServerErrorContainer($error_text, |
$error_code, | $error_code, |
$message); | $message); |
} | } |
} | } |
/** | /** |
* A response with a status of Auth_OpenID_CANCEL. Indicates that the | * A response with a status of Auth_OpenID_CANCEL. Indicates that the |
* user cancelled the OpenID authentication request. This has two | * user cancelled the OpenID authentication request. This has two |
* relevant attributes: | * relevant attributes: |
* | * |
* claimed_id - The identity URL for which authentication was | * claimed_id - The identity URL for which authentication was |
* attempted, if it can be determined. Otherwise, null. | * attempted, if it can be determined. Otherwise, null. |
* | * |
* status - Auth_OpenID_SUCCESS. | * status - Auth_OpenID_SUCCESS. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_CancelResponse extends Auth_OpenID_ConsumerResponse { | class Auth_OpenID_CancelResponse extends Auth_OpenID_ConsumerResponse { |
var $status = Auth_OpenID_CANCEL; | var $status = Auth_OpenID_CANCEL; |
function Auth_OpenID_CancelResponse($endpoint) | function Auth_OpenID_CancelResponse($endpoint) |
{ | { |
$this->setEndpoint($endpoint); | $this->setEndpoint($endpoint); |
} | } |
} | } |
/** | /** |
* A response with a status of Auth_OpenID_SETUP_NEEDED. Indicates | * A response with a status of Auth_OpenID_SETUP_NEEDED. Indicates |
* that the request was in immediate mode, and the server is unable to | * that the request was in immediate mode, and the server is unable to |
* authenticate the user without further interaction. | * authenticate the user without further interaction. |
* | * |
* claimed_id - The identity URL for which authentication was | * claimed_id - The identity URL for which authentication was |
* attempted. | * attempted. |
* | * |
* setup_url - A URL that can be used to send the user to the server | * setup_url - A URL that can be used to send the user to the server |
* to set up for authentication. The user should be redirected in to | * to set up for authentication. The user should be redirected in to |
* the setup_url, either in the current window or in a new browser | * the setup_url, either in the current window or in a new browser |
* window. Null in OpenID 2. | * window. Null in OpenID 2. |
* | * |
* status - Auth_OpenID_SETUP_NEEDED. | * status - Auth_OpenID_SETUP_NEEDED. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_SetupNeededResponse extends Auth_OpenID_ConsumerResponse { | class Auth_OpenID_SetupNeededResponse extends Auth_OpenID_ConsumerResponse { |
var $status = Auth_OpenID_SETUP_NEEDED; | var $status = Auth_OpenID_SETUP_NEEDED; |
function Auth_OpenID_SetupNeededResponse($endpoint, | function Auth_OpenID_SetupNeededResponse($endpoint, |
$setup_url = null) | $setup_url = null) |
{ | { |
$this->setEndpoint($endpoint); | $this->setEndpoint($endpoint); |
$this->setup_url = $setup_url; | $this->setup_url = $setup_url; |
} | } |
} | } |
<?php | |
/** | |
* CryptUtil: A suite of wrapper utility functions for the OpenID | |
* library. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @access private | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
if (!defined('Auth_OpenID_RAND_SOURCE')) { | |
/** | |
* The filename for a source of random bytes. Define this yourself | |
* if you have a different source of randomness. | |
*/ | |
define('Auth_OpenID_RAND_SOURCE', '/dev/urandom'); | |
} | |
class Auth_OpenID_CryptUtil { | |
/** | |
* Get the specified number of random bytes. | |
* | |
* Attempts to use a cryptographically secure (not predictable) | |
* source of randomness if available. If there is no high-entropy | |
* randomness source available, it will fail. As a last resort, | |
* for non-critical systems, define | |
* <code>Auth_OpenID_RAND_SOURCE</code> as <code>null</code>, and | |
* the code will fall back on a pseudo-random number generator. | |
* | |
* @param int $num_bytes The length of the return value | |
* @return string $bytes random bytes | |
*/ | |
static function getBytes($num_bytes) | |
{ | |
static $f = null; | |
$bytes = ''; | |
if ($f === null) { | |
if (Auth_OpenID_RAND_SOURCE === null) { | |
$f = false; | |
} else { | |
$f = @fopen(Auth_OpenID_RAND_SOURCE, "r"); | |
/*if ($f === false) { | |
$msg = 'Define Auth_OpenID_RAND_SOURCE as null to ' . | |
' continue with an insecure random number generator.'; | |
trigger_error($msg, E_USER_ERROR); | |
}*/ | |
} | |
} | |
if ($f === false) { | |
// pseudorandom used | |
$bytes = ''; | |
for ($i = 0; $i < $num_bytes; $i += 4) { | |
$bytes .= pack('L', mt_rand()); | |
} | |
$bytes = substr($bytes, 0, $num_bytes); | |
} else { | |
$bytes = fread($f, $num_bytes); | |
} | |
return $bytes; | |
} | |
/** | |
* Produce a string of length random bytes, chosen from chrs. If | |
* $chrs is null, the resulting string may contain any characters. | |
* | |
* @param integer $length The length of the resulting | |
* randomly-generated string | |
* @param string $chrs A string of characters from which to choose | |
* to build the new string | |
* @return string $result A string of randomly-chosen characters | |
* from $chrs | |
*/ | |
static function randomString($length, $population = null) | |
{ | |
if ($population === null) { | |
return Auth_OpenID_CryptUtil::getBytes($length); | |
} | |
$popsize = strlen($population); | |
if ($popsize > 256) { | |
$msg = 'More than 256 characters supplied to ' . __FUNCTION__; | |
trigger_error($msg, E_USER_ERROR); | |
} | |
$duplicate = 256 % $popsize; | |
$str = ""; | |
for ($i = 0; $i < $length; $i++) { | |
do { | |
$n = ord(Auth_OpenID_CryptUtil::getBytes(1)); | |
} while ($n < $duplicate); | |
$n %= $popsize; | |
$str .= $population[$n]; | |
} | |
return $str; | |
} | |
static function constEq($s1, $s2) | |
{ | |
if (strlen($s1) != strlen($s2)) { | |
return false; | |
} | |
$result = true; | |
$length = strlen($s1); | |
for ($i = 0; $i < $length; $i++) { | |
$result &= ($s1[$i] == $s2[$i]); | |
} | |
return $result; | |
} | |
} | |
<?php | |
/** | |
* The Auth_OpenID_DatabaseConnection class, which is used to emulate | |
* a PEAR database connection. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* An empty base class intended to emulate PEAR connection | |
* functionality in applications that supply their own database | |
* abstraction mechanisms. See {@link Auth_OpenID_SQLStore} for more | |
* information. You should subclass this class if you need to create | |
* an SQL store that needs to access its database using an | |
* application's database abstraction layer instead of a PEAR database | |
* connection. Any subclass of Auth_OpenID_DatabaseConnection MUST | |
* adhere to the interface specified here. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_DatabaseConnection { | |
/** | |
* Sets auto-commit mode on this database connection. | |
* | |
* @param bool $mode True if auto-commit is to be used; false if | |
* not. | |
*/ | |
function autoCommit($mode) | |
{ | |
} | |
/** | |
* Run an SQL query with the specified parameters, if any. | |
* | |
* @param string $sql An SQL string with placeholders. The | |
* placeholders are assumed to be specific to the database engine | |
* for this connection. | |
* | |
* @param array $params An array of parameters to insert into the | |
* SQL string using this connection's escaping mechanism. | |
* | |
* @return mixed $result The result of calling this connection's | |
* internal query function. The type of result depends on the | |
* underlying database engine. This method is usually used when | |
* the result of a query is not important, like a DDL query. | |
*/ | |
function query($sql, $params = array()) | |
{ | |
} | |
/** | |
* Starts a transaction on this connection, if supported. | |
*/ | |
function begin() | |
{ | |
} | |
/** | |
* Commits a transaction on this connection, if supported. | |
*/ | |
function commit() | |
{ | |
} | |
/** | |
* Performs a rollback on this connection, if supported. | |
*/ | |
function rollback() | |
{ | |
} | |
/** | |
* Run an SQL query and return the first column of the first row | |
* of the result set, if any. | |
* | |
* @param string $sql An SQL string with placeholders. The | |
* placeholders are assumed to be specific to the database engine | |
* for this connection. | |
* | |
* @param array $params An array of parameters to insert into the | |
* SQL string using this connection's escaping mechanism. | |
* | |
* @return mixed $result The value of the first column of the | |
* first row of the result set. False if no such result was | |
* found. | |
*/ | |
function getOne($sql, $params = array()) | |
{ | |
} | |
/** | |
* Run an SQL query and return the first row of the result set, if | |
* any. | |
* | |
* @param string $sql An SQL string with placeholders. The | |
* placeholders are assumed to be specific to the database engine | |
* for this connection. | |
* | |
* @param array $params An array of parameters to insert into the | |
* SQL string using this connection's escaping mechanism. | |
* | |
* @return array $result The first row of the result set, if any, | |
* keyed on column name. False if no such result was found. | |
*/ | |
function getRow($sql, $params = array()) | |
{ | |
} | |
/** | |
* Run an SQL query with the specified parameters, if any. | |
* | |
* @param string $sql An SQL string with placeholders. The | |
* placeholders are assumed to be specific to the database engine | |
* for this connection. | |
* | |
* @param array $params An array of parameters to insert into the | |
* SQL string using this connection's escaping mechanism. | |
* | |
* @return array $result An array of arrays representing the | |
* result of the query; each array is keyed on column name. | |
*/ | |
function getAll($sql, $params = array()) | |
{ | |
} | |
} | |
<?php | |
/** | |
* The OpenID library's Diffie-Hellman implementation. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @access private | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
require_once 'Auth/OpenID.php'; | |
require_once 'Auth/OpenID/BigMath.php'; | |
function Auth_OpenID_getDefaultMod() | |
{ | |
return '155172898181473697471232257763715539915724801'. | |
'966915404479707795314057629378541917580651227423'. | |
'698188993727816152646631438561595825688188889951'. | |
'272158842675419950341258706556549803580104870537'. | |
'681476726513255747040765857479291291572334510643'. | |
'245094715007229621094194349783925984760375594985'. | |
'848253359305585439638443'; | |
} | |
function Auth_OpenID_getDefaultGen() | |
{ | |
return '2'; | |
} | |
/** | |
* The Diffie-Hellman key exchange class. This class relies on | |
* {@link Auth_OpenID_MathLibrary} to perform large number operations. | |
* | |
* @access private | |
* @package OpenID | |
*/ | |
class Auth_OpenID_DiffieHellman { | |
var $mod; | |
var $gen; | |
var $private; | |
var $lib = null; | |
function Auth_OpenID_DiffieHellman($mod = null, $gen = null, | |
$private = null, $lib = null) | |
{ | |
if ($lib === null) { | |
$this->lib = Auth_OpenID_getMathLib(); | |
} else { | |
$this->lib = $lib; | |
} | |
if ($mod === null) { | |
$this->mod = $this->lib->init(Auth_OpenID_getDefaultMod()); | |
} else { | |
$this->mod = $mod; | |
} | |
if ($gen === null) { | |
$this->gen = $this->lib->init(Auth_OpenID_getDefaultGen()); | |
} else { | |
$this->gen = $gen; | |
} | |
if ($private === null) { | |
$r = $this->lib->rand($this->mod); | |
$this->private = $this->lib->add($r, 1); | |
} else { | |
$this->private = $private; | |
} | |
$this->public = $this->lib->powmod($this->gen, $this->private, | |
$this->mod); | |
} | |
function getSharedSecret($composite) | |
{ | |
return $this->lib->powmod($composite, $this->private, $this->mod); | |
} | |
function getPublicKey() | |
{ | |
return $this->public; | |
} | |
function usingDefaultValues() | |
{ | |
return ($this->mod == Auth_OpenID_getDefaultMod() && | |
$this->gen == Auth_OpenID_getDefaultGen()); | |
} | |
function xorSecret($composite, $secret, $hash_func) | |
{ | |
$dh_shared = $this->getSharedSecret($composite); | |
$dh_shared_str = $this->lib->longToBinary($dh_shared); | |
$hash_dh_shared = $hash_func($dh_shared_str); | |
$xsecret = ""; | |
for ($i = 0; $i < Auth_OpenID::bytes($secret); $i++) { | |
$xsecret .= chr(ord($secret[$i]) ^ ord($hash_dh_shared[$i])); | |
} | |
return $xsecret; | |
} | |
} | |
<?php | |
/** | |
* The OpenID and Yadis discovery implementation for OpenID 1.2. | |
*/ | |
require_once "Auth/OpenID.php"; | |
require_once "Auth/OpenID/Parse.php"; | |
require_once "Auth/OpenID/Message.php"; | |
require_once "Auth/Yadis/XRIRes.php"; | |
require_once "Auth/Yadis/Yadis.php"; | |
// XML namespace value | |
define('Auth_OpenID_XMLNS_1_0', 'http://openid.net/xmlns/1.0'); | |
// Yadis service types | |
define('Auth_OpenID_TYPE_1_2', 'http://openid.net/signon/1.2'); | |
define('Auth_OpenID_TYPE_1_1', 'http://openid.net/signon/1.1'); | |
define('Auth_OpenID_TYPE_1_0', 'http://openid.net/signon/1.0'); | |
define('Auth_OpenID_TYPE_2_0_IDP', 'http://specs.openid.net/auth/2.0/server'); | |
define('Auth_OpenID_TYPE_2_0', 'http://specs.openid.net/auth/2.0/signon'); | |
define('Auth_OpenID_RP_RETURN_TO_URL_TYPE', | |
'http://specs.openid.net/auth/2.0/return_to'); | |
function Auth_OpenID_getOpenIDTypeURIs() | |
{ | |
return array(Auth_OpenID_TYPE_2_0_IDP, | |
Auth_OpenID_TYPE_2_0, | |
Auth_OpenID_TYPE_1_2, | |
Auth_OpenID_TYPE_1_1, | |
Auth_OpenID_TYPE_1_0); | |
} | |
function Auth_OpenID_getOpenIDConsumerTypeURIs() | |
{ | |
return array(Auth_OpenID_RP_RETURN_TO_URL_TYPE); | |
} | |
/* | |
* Provides a user-readable interpretation of a type uri. | |
* Useful for error messages. | |
*/ | |
function Auth_OpenID_getOpenIDTypeName($type_uri) { | |
switch ($type_uri) { | |
case Auth_OpenID_TYPE_2_0_IDP: | |
return 'OpenID 2.0 IDP'; | |
case Auth_OpenID_TYPE_2_0: | |
return 'OpenID 2.0'; | |
case Auth_OpenID_TYPE_1_2: | |
return 'OpenID 1.2'; | |
case Auth_OpenID_TYPE_1_1: | |
return 'OpenID 1.1'; | |
case Auth_OpenID_TYPE_1_0: | |
return 'OpenID 1.0'; | |
case Auth_OpenID_RP_RETURN_TO_URL_TYPE: | |
return 'OpenID relying party'; | |
} | |
} | |
/** | |
* Object representing an OpenID service endpoint. | |
*/ | |
class Auth_OpenID_ServiceEndpoint { | |
function Auth_OpenID_ServiceEndpoint() | |
{ | |
$this->claimed_id = null; | |
$this->server_url = null; | |
$this->type_uris = array(); | |
$this->local_id = null; | |
$this->canonicalID = null; | |
$this->used_yadis = false; // whether this came from an XRDS | |
$this->display_identifier = null; | |
} | |
function getDisplayIdentifier() | |
{ | |
if ($this->display_identifier) { | |
return $this->display_identifier; | |
} | |
if (! $this->claimed_id) { | |
return $this->claimed_id; | |
} | |
$parsed = parse_url($this->claimed_id); | |
$scheme = $parsed['scheme']; | |
$host = $parsed['host']; | |
$path = $parsed['path']; | |
if (array_key_exists('query', $parsed)) { | |
$query = $parsed['query']; | |
$no_frag = "$scheme://$host$path?$query"; | |
} else { | |
$no_frag = "$scheme://$host$path"; | |
} | |
return $no_frag; | |
} | |
function usesExtension($extension_uri) | |
{ | |
return in_array($extension_uri, $this->type_uris); | |
} | |
function preferredNamespace() | |
{ | |
if (in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris) || | |
in_array(Auth_OpenID_TYPE_2_0, $this->type_uris)) { | |
return Auth_OpenID_OPENID2_NS; | |
} else { | |
return Auth_OpenID_OPENID1_NS; | |
} | |
} | |
/* | |
* Query this endpoint to see if it has any of the given type | |
* URIs. This is useful for implementing other endpoint classes | |
* that e.g. need to check for the presence of multiple versions | |
* of a single protocol. | |
* | |
* @param $type_uris The URIs that you wish to check | |
* | |
* @return all types that are in both in type_uris and | |
* $this->type_uris | |
*/ | |
function matchTypes($type_uris) | |
{ | |
$result = array(); | |
foreach ($type_uris as $test_uri) { | |
if ($this->supportsType($test_uri)) { | |
$result[] = $test_uri; | |
} | |
} | |
return $result; | |
} | |
function supportsType($type_uri) | |
{ | |
// Does this endpoint support this type? | |
return ((in_array($type_uri, $this->type_uris)) || | |
(($type_uri == Auth_OpenID_TYPE_2_0) && | |
$this->isOPIdentifier())); | |
} | |
function compatibilityMode() | |
{ | |
return $this->preferredNamespace() != Auth_OpenID_OPENID2_NS; | |
} | |
function isOPIdentifier() | |
{ | |
return in_array(Auth_OpenID_TYPE_2_0_IDP, $this->type_uris); | |
} | |
static function fromOPEndpointURL($op_endpoint_url) | |
{ | |
// Construct an OP-Identifier OpenIDServiceEndpoint object for | |
// a given OP Endpoint URL | |
$obj = new Auth_OpenID_ServiceEndpoint(); | |
$obj->server_url = $op_endpoint_url; | |
$obj->type_uris = array(Auth_OpenID_TYPE_2_0_IDP); | |
return $obj; | |
} | |
function parseService($yadis_url, $uri, $type_uris, $service_element) | |
{ | |
// Set the state of this object based on the contents of the | |
// service element. Return true if successful, false if not | |
// (if findOPLocalIdentifier returns false). | |
$this->type_uris = $type_uris; | |
$this->server_url = $uri; | |
$this->used_yadis = true; | |
if (!$this->isOPIdentifier()) { | |
$this->claimed_id = $yadis_url; | |
$this->local_id = Auth_OpenID_findOPLocalIdentifier( | |
$service_element, | |
$this->type_uris); | |
if ($this->local_id === false) { | |
return false; | |
} | |
} | |
return true; | |
} | |
function getLocalID() | |
{ | |
// Return the identifier that should be sent as the | |
// openid.identity_url parameter to the server. | |
if ($this->local_id === null && $this->canonicalID === null) { | |
return $this->claimed_id; | |
} else { | |
if ($this->local_id) { | |
return $this->local_id; | |
} else { | |
return $this->canonicalID; | |
} | |
} | |
} | |
/* | |
* Parse the given document as XRDS looking for OpenID consumer services. | |
* | |
* @return array of Auth_OpenID_ServiceEndpoint or null if the | |
* document cannot be parsed. | |
*/ | |
function consumerFromXRDS($uri, $xrds_text) | |
{ | |
$xrds =& Auth_Yadis_XRDS::parseXRDS($xrds_text); | |
if ($xrds) { | |
$yadis_services = | |
$xrds->services(array('filter_MatchesAnyOpenIDConsumerType')); | |
return Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services); | |
} | |
return null; | |
} | |
/* | |
* Parse the given document as XRDS looking for OpenID services. | |
* | |
* @return array of Auth_OpenID_ServiceEndpoint or null if the | |
* document cannot be parsed. | |
*/ | |
static function fromXRDS($uri, $xrds_text) | |
{ | |
$xrds = Auth_Yadis_XRDS::parseXRDS($xrds_text); | |
if ($xrds) { | |
$yadis_services = | |
$xrds->services(array('filter_MatchesAnyOpenIDType')); | |
return Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services); | |
} | |
return null; | |
} | |
/* | |
* Create endpoints from a DiscoveryResult. | |
* | |
* @param discoveryResult Auth_Yadis_DiscoveryResult | |
* @return array of Auth_OpenID_ServiceEndpoint or null if | |
* endpoints cannot be created. | |
*/ | |
static function fromDiscoveryResult($discoveryResult) | |
{ | |
if ($discoveryResult->isXRDS()) { | |
return Auth_OpenID_ServiceEndpoint::fromXRDS( | |
$discoveryResult->normalized_uri, | |
$discoveryResult->response_text); | |
} else { | |
return Auth_OpenID_ServiceEndpoint::fromHTML( | |
$discoveryResult->normalized_uri, | |
$discoveryResult->response_text); | |
} | |
} | |
static function fromHTML($uri, $html) | |
{ | |
$discovery_types = array( | |
array(Auth_OpenID_TYPE_2_0, | |
'openid2.provider', 'openid2.local_id'), | |
array(Auth_OpenID_TYPE_1_1, | |
'openid.server', 'openid.delegate') | |
); | |
$services = array(); | |
foreach ($discovery_types as $triple) { | |
list($type_uri, $server_rel, $delegate_rel) = $triple; | |
$urls = Auth_OpenID_legacy_discover($html, $server_rel, | |
$delegate_rel); | |
if ($urls === false) { | |
continue; | |
} | |
list($delegate_url, $server_url) = $urls; | |
$service = new Auth_OpenID_ServiceEndpoint(); | |
$service->claimed_id = $uri; | |
$service->local_id = $delegate_url; | |
$service->server_url = $server_url; | |
$service->type_uris = array($type_uri); | |
$services[] = $service; | |
} | |
return $services; | |
} | |
function copy() | |
{ | |
$x = new Auth_OpenID_ServiceEndpoint(); | |
$x->claimed_id = $this->claimed_id; | |
$x->server_url = $this->server_url; | |
$x->type_uris = $this->type_uris; | |
$x->local_id = $this->local_id; | |
$x->canonicalID = $this->canonicalID; | |
$x->used_yadis = $this->used_yadis; | |
return $x; | |
} | |
} | |
function Auth_OpenID_findOPLocalIdentifier($service, $type_uris) | |
{ | |
// Extract a openid:Delegate value from a Yadis Service element. | |
// If no delegate is found, returns null. Returns false on | |
// discovery failure (when multiple delegate/localID tags have | |
// different values). | |
$service->parser->registerNamespace('openid', | |
Auth_OpenID_XMLNS_1_0); | |
$service->parser->registerNamespace('xrd', | |
Auth_Yadis_XMLNS_XRD_2_0); | |
$parser = $service->parser; | |
$permitted_tags = array(); | |
if (in_array(Auth_OpenID_TYPE_1_1, $type_uris) || | |
in_array(Auth_OpenID_TYPE_1_0, $type_uris)) { | |
$permitted_tags[] = 'openid:Delegate'; | |
} | |
if (in_array(Auth_OpenID_TYPE_2_0, $type_uris)) { | |
$permitted_tags[] = 'xrd:LocalID'; | |
} | |
$local_id = null; | |
foreach ($permitted_tags as $tag_name) { | |
$tags = $service->getElements($tag_name); | |
foreach ($tags as $tag) { | |
$content = $parser->content($tag); | |
if ($local_id === null) { | |
$local_id = $content; | |
} else if ($local_id != $content) { | |
return false; | |
} | |
} | |
} | |
return $local_id; | |
} | |
function filter_MatchesAnyOpenIDType($service) | |
{ | |
$uris = $service->getTypes(); | |
foreach ($uris as $uri) { | |
if (in_array($uri, Auth_OpenID_getOpenIDTypeURIs())) { | |
return true; | |
} | |
} | |
return false; | |
} | |
function filter_MatchesAnyOpenIDConsumerType(&$service) | |
{ | |
$uris = $service->getTypes(); | |
foreach ($uris as $uri) { | |
if (in_array($uri, Auth_OpenID_getOpenIDConsumerTypeURIs())) { | |
return true; | |
} | |
} | |
return false; | |
} | |
function Auth_OpenID_bestMatchingService($service, $preferred_types) | |
{ | |
// Return the index of the first matching type, or something | |
// higher if no type matches. | |
// | |
// This provides an ordering in which service elements that | |
// contain a type that comes earlier in the preferred types list | |
// come before service elements that come later. If a service | |
// element has more than one type, the most preferred one wins. | |
foreach ($preferred_types as $index => $typ) { | |
if (in_array($typ, $service->type_uris)) { | |
return $index; | |
} | |
} | |
return count($preferred_types); | |
} | |
function Auth_OpenID_arrangeByType($service_list, $preferred_types) | |
{ | |
// Rearrange service_list in a new list so services are ordered by | |
// types listed in preferred_types. Return the new list. | |
// Build a list with the service elements in tuples whose | |
// comparison will prefer the one with the best matching service | |
$prio_services = array(); | |
foreach ($service_list as $index => $service) { | |
$prio_services[] = array(Auth_OpenID_bestMatchingService($service, | |
$preferred_types), | |
$index, $service); | |
} | |
sort($prio_services); | |
// Now that the services are sorted by priority, remove the sort | |
// keys from the list. | |
foreach ($prio_services as $index => $s) { | |
$prio_services[$index] = $prio_services[$index][2]; | |
} | |
return $prio_services; | |
} | |
// Extract OP Identifier services. If none found, return the rest, | |
// sorted with most preferred first according to | |
// OpenIDServiceEndpoint.openid_type_uris. | |
// | |
// openid_services is a list of OpenIDServiceEndpoint objects. | |
// | |
// Returns a list of OpenIDServiceEndpoint objects.""" | |
function Auth_OpenID_getOPOrUserServices($openid_services) | |
{ | |
$op_services = Auth_OpenID_arrangeByType($openid_services, | |
array(Auth_OpenID_TYPE_2_0_IDP)); | |
$openid_services = Auth_OpenID_arrangeByType($openid_services, | |
Auth_OpenID_getOpenIDTypeURIs()); | |
if ($op_services) { | |
return $op_services; | |
} else { | |
return $openid_services; | |
} | |
} | |
function Auth_OpenID_makeOpenIDEndpoints($uri, $yadis_services) | |
{ | |
$s = array(); | |
if (!$yadis_services) { | |
return $s; | |
} | |
foreach ($yadis_services as $service) { | |
$type_uris = $service->getTypes(); | |
$uris = $service->getURIs(); | |
// If any Type URIs match and there is an endpoint URI | |
// specified, then this is an OpenID endpoint | |
if ($type_uris && | |
$uris) { | |
foreach ($uris as $service_uri) { | |
$openid_endpoint = new Auth_OpenID_ServiceEndpoint(); | |
if ($openid_endpoint->parseService($uri, | |
$service_uri, | |
$type_uris, | |
$service)) { | |
$s[] = $openid_endpoint; | |
} | |
} | |
} | |
} | |
return $s; | |
} | |
function Auth_OpenID_discoverWithYadis($uri, $fetcher, | |
$endpoint_filter='Auth_OpenID_getOPOrUserServices', | |
$discover_function=null) | |
{ | |
// Discover OpenID services for a URI. Tries Yadis and falls back | |
// on old-style <link rel='...'> discovery if Yadis fails. | |
// Might raise a yadis.discover.DiscoveryFailure if no document | |
// came back for that URI at all. I don't think falling back to | |
// OpenID 1.0 discovery on the same URL will help, so don't bother | |
// to catch it. | |
if ($discover_function === null) { | |
$discover_function = array('Auth_Yadis_Yadis', 'discover'); | |
} | |
$openid_services = array(); | |
$response = call_user_func_array($discover_function, | |
array($uri, $fetcher)); | |
$yadis_url = $response->normalized_uri; | |
$yadis_services = array(); | |
if ($response->isFailure() && !$response->isXRDS()) { | |
return array($uri, array()); | |
} | |
$openid_services = Auth_OpenID_ServiceEndpoint::fromXRDS( | |
$yadis_url, | |
$response->response_text); | |
if (!$openid_services) { | |
if ($response->isXRDS()) { | |
return Auth_OpenID_discoverWithoutYadis($uri, | |
$fetcher); | |
} | |
// Try to parse the response as HTML to get OpenID 1.0/1.1 | |
// <link rel="..."> | |
$openid_services = Auth_OpenID_ServiceEndpoint::fromHTML( | |
$yadis_url, | |
$response->response_text); | |
} | |
$openid_services = call_user_func_array($endpoint_filter, | |
array($openid_services)); | |
return array($yadis_url, $openid_services); | |
} | |
function Auth_OpenID_discoverURI($uri, $fetcher) | |
{ | |
$uri = Auth_OpenID::normalizeUrl($uri); | |
return Auth_OpenID_discoverWithYadis($uri, $fetcher); | |
} | |
function Auth_OpenID_discoverWithoutYadis($uri, $fetcher) | |
{ | |
$http_resp = @$fetcher->get($uri); | |
if ($http_resp->status != 200 and $http_resp->status != 206) { | |
return array($uri, array()); | |
} | |
$identity_url = $http_resp->final_url; | |
// Try to parse the response as HTML to get OpenID 1.0/1.1 <link | |
// rel="..."> | |
$openid_services = Auth_OpenID_ServiceEndpoint::fromHTML( | |
$identity_url, | |
$http_resp->body); | |
return array($identity_url, $openid_services); | |
} | |
function Auth_OpenID_discoverXRI($iname, $fetcher) | |
{ | |
$resolver = new Auth_Yadis_ProxyResolver($fetcher); | |
list($canonicalID, $yadis_services) = | |
$resolver->query($iname, | |
Auth_OpenID_getOpenIDTypeURIs(), | |
array('filter_MatchesAnyOpenIDType')); | |
$openid_services = Auth_OpenID_makeOpenIDEndpoints($iname, | |
$yadis_services); | |
$openid_services = Auth_OpenID_getOPOrUserServices($openid_services); | |
for ($i = 0; $i < count($openid_services); $i++) { | |
$openid_services[$i]->canonicalID = $canonicalID; | |
$openid_services[$i]->claimed_id = $canonicalID; | |
$openid_services[$i]->display_identifier = $iname; | |
} | |
// FIXME: returned xri should probably be in some normal form | |
return array($iname, $openid_services); | |
} | |
function Auth_OpenID_discover($uri, $fetcher) | |
{ | |
// If the fetcher (i.e., PHP) doesn't support SSL, we can't do | |
// discovery on an HTTPS URL. | |
if ($fetcher->isHTTPS($uri) && !$fetcher->supportsSSL()) { | |
return array($uri, array()); | |
} | |
if (Auth_Yadis_identifierScheme($uri) == 'XRI') { | |
$result = Auth_OpenID_discoverXRI($uri, $fetcher); | |
} else { | |
$result = Auth_OpenID_discoverURI($uri, $fetcher); | |
} | |
// If the fetcher doesn't support SSL, we can't interact with | |
// HTTPS server URLs; remove those endpoints from the list. | |
if (!$fetcher->supportsSSL()) { | |
$http_endpoints = array(); | |
list($new_uri, $endpoints) = $result; | |
foreach ($endpoints as $e) { | |
if (!$fetcher->isHTTPS($e->server_url)) { | |
$http_endpoints[] = $e; | |
} | |
} | |
$result = array($new_uri, $http_endpoints); | |
} | |
return $result; | |
} | |
<?php | |
/** | |
* This file supplies a dumb store backend for OpenID servers and | |
* consumers. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Import the interface for creating a new store class. | |
*/ | |
require_once 'Auth/OpenID/Interface.php'; | |
require_once 'Auth/OpenID/HMAC.php'; | |
/** | |
* This is a store for use in the worst case, when you have no way of | |
* saving state on the consumer site. Using this store makes the | |
* consumer vulnerable to replay attacks, as it's unable to use | |
* nonces. Avoid using this store if it is at all possible. | |
* | |
* Most of the methods of this class are implementation details. | |
* Users of this class need to worry only about the constructor. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_DumbStore extends Auth_OpenID_OpenIDStore { | |
/** | |
* Creates a new {@link Auth_OpenID_DumbStore} instance. For the security | |
* of the tokens generated by the library, this class attempts to | |
* at least have a secure implementation of getAuthKey. | |
* | |
* When you create an instance of this class, pass in a secret | |
* phrase. The phrase is hashed with sha1 to make it the correct | |
* length and form for an auth key. That allows you to use a long | |
* string as the secret phrase, which means you can make it very | |
* difficult to guess. | |
* | |
* Each {@link Auth_OpenID_DumbStore} instance that is created for use by | |
* your consumer site needs to use the same $secret_phrase. | |
* | |
* @param string secret_phrase The phrase used to create the auth | |
* key returned by getAuthKey | |
*/ | |
function Auth_OpenID_DumbStore($secret_phrase) | |
{ | |
$this->auth_key = Auth_OpenID_SHA1($secret_phrase); | |
} | |
/** | |
* This implementation does nothing. | |
*/ | |
function storeAssociation($server_url, $association) | |
{ | |
} | |
/** | |
* This implementation always returns null. | |
*/ | |
function getAssociation($server_url, $handle = null) | |
{ | |
return null; | |
} | |
/** | |
* This implementation always returns false. | |
*/ | |
function removeAssociation($server_url, $handle) | |
{ | |
return false; | |
} | |
/** | |
* In a system truly limited to dumb mode, nonces must all be | |
* accepted. This therefore always returns true, which makes | |
* replay attacks feasible. | |
*/ | |
function useNonce($server_url, $timestamp, $salt) | |
{ | |
return true; | |
} | |
/** | |
* This method returns the auth key generated by the constructor. | |
*/ | |
function getAuthKey() | |
{ | |
return $this->auth_key; | |
} | |
} | |
<?php | |
/** | |
* An interface for OpenID extensions. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Require the Message implementation. | |
*/ | |
require_once 'Auth/OpenID/Message.php'; | |
/** | |
* A base class for accessing extension request and response data for | |
* the OpenID 2 protocol. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_Extension { | |
/** | |
* ns_uri: The namespace to which to add the arguments for this | |
* extension | |
*/ | |
var $ns_uri = null; | |
var $ns_alias = null; | |
/** | |
* Get the string arguments that should be added to an OpenID | |
* message for this extension. | |
*/ | |
function getExtensionArgs() | |
{ | |
return null; | |
} | |
/** | |
* Add the arguments from this extension to the provided message. | |
* | |
* Returns the message with the extension arguments added. | |
*/ | |
function toMessage($message) | |
{ | |
$implicit = $message->isOpenID1(); | |
$added = $message->namespaces->addAlias($this->ns_uri, | |
$this->ns_alias, | |
$implicit); | |
if ($added === null) { | |
if ($message->namespaces->getAlias($this->ns_uri) != | |
$this->ns_alias) { | |
return null; | |
} | |
} | |
$message->updateArgs($this->ns_uri, | |
$this->getExtensionArgs()); | |
return $message; | |
} | |
} | |
<?php | |
/** | |
* This file supplies a Memcached store backend for OpenID servers and | |
* consumers. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Require base class for creating a new interface. | |
*/ | |
require_once 'Auth/OpenID.php'; | |
require_once 'Auth/OpenID/Interface.php'; | |
require_once 'Auth/OpenID/HMAC.php'; | |
require_once 'Auth/OpenID/Nonce.php'; | |
/** | |
* This is a filesystem-based store for OpenID associations and | |
* nonces. This store should be safe for use in concurrent systems on | |
* both windows and unix (excluding NFS filesystems). There are a | |
* couple race conditions in the system, but those failure cases have | |
* been set up in such a way that the worst-case behavior is someone | |
* having to try to log in a second time. | |
* | |
* Most of the methods of this class are implementation details. | |
* People wishing to just use this store need only pay attention to | |
* the constructor. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore { | |
/** | |
* Initializes a new {@link Auth_OpenID_FileStore}. This | |
* initializes the nonce and association directories, which are | |
* subdirectories of the directory passed in. | |
* | |
* @param string $directory This is the directory to put the store | |
* directories in. | |
*/ | |
function Auth_OpenID_FileStore($directory) | |
{ | |
if (!Auth_OpenID::ensureDir($directory)) { | |
trigger_error('Not a directory and failed to create: ' | |
. $directory, E_USER_ERROR); | |
} | |
$directory = realpath($directory); | |
$this->directory = $directory; | |
$this->active = true; | |
$this->nonce_dir = $directory . DIRECTORY_SEPARATOR . 'nonces'; | |
$this->association_dir = $directory . DIRECTORY_SEPARATOR . | |
'associations'; | |
// Temp dir must be on the same filesystem as the assciations | |
// $directory. | |
$this->temp_dir = $directory . DIRECTORY_SEPARATOR . 'temp'; | |
$this->max_nonce_age = 6 * 60 * 60; // Six hours, in seconds | |
if (!$this->_setup()) { | |
trigger_error('Failed to initialize OpenID file store in ' . | |
$directory, E_USER_ERROR); | |
} | |
} | |
function destroy() | |
{ | |
Auth_OpenID_FileStore::_rmtree($this->directory); | |
$this->active = false; | |
} | |
/** | |
* Make sure that the directories in which we store our data | |
* exist. | |
* | |
* @access private | |
*/ | |
function _setup() | |
{ | |
return (Auth_OpenID::ensureDir($this->nonce_dir) && | |
Auth_OpenID::ensureDir($this->association_dir) && | |
Auth_OpenID::ensureDir($this->temp_dir)); | |
} | |
/** | |
* Create a temporary file on the same filesystem as | |
* $this->association_dir. | |
* | |
* The temporary directory should not be cleaned if there are any | |
* processes using the store. If there is no active process using | |
* the store, it is safe to remove all of the files in the | |
* temporary directory. | |
* | |
* @return array ($fd, $filename) | |
* @access private | |
*/ | |
function _mktemp() | |
{ | |
$name = Auth_OpenID_FileStore::_mkstemp($dir = $this->temp_dir); | |
$file_obj = @fopen($name, 'wb'); | |
if ($file_obj !== false) { | |
return array($file_obj, $name); | |
} else { | |
Auth_OpenID_FileStore::_removeIfPresent($name); | |
} | |
} | |
function cleanupNonces() | |
{ | |
global $Auth_OpenID_SKEW; | |
$nonces = Auth_OpenID_FileStore::_listdir($this->nonce_dir); | |
$now = time(); | |
$removed = 0; | |
// Check all nonces for expiry | |
foreach ($nonces as $nonce_fname) { | |
$base = basename($nonce_fname); | |
$parts = explode('-', $base, 2); | |
$timestamp = $parts[0]; | |
$timestamp = intval($timestamp, 16); | |
if (abs($timestamp - $now) > $Auth_OpenID_SKEW) { | |
Auth_OpenID_FileStore::_removeIfPresent($nonce_fname); | |
$removed += 1; | |
} | |
} | |
return $removed; | |
} | |
/** | |
* Create a unique filename for a given server url and | |
* handle. This implementation does not assume anything about the | |
* format of the handle. The filename that is returned will | |
* contain the domain name from the server URL for ease of human | |
* inspection of the data directory. | |
* | |
* @return string $filename | |
*/ | |
function getAssociationFilename($server_url, $handle) | |
{ | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return null; | |
} | |
if (strpos($server_url, '://') === false) { | |
trigger_error(sprintf("Bad server URL: %s", $server_url), | |
E_USER_WARNING); | |
return null; | |
} | |
list($proto, $rest) = explode('://', $server_url, 2); | |
$parts = explode('/', $rest); | |
$domain = Auth_OpenID_FileStore::_filenameEscape($parts[0]); | |
$url_hash = Auth_OpenID_FileStore::_safe64($server_url); | |
if ($handle) { | |
$handle_hash = Auth_OpenID_FileStore::_safe64($handle); | |
} else { | |
$handle_hash = ''; | |
} | |
$filename = sprintf('%s-%s-%s-%s', $proto, $domain, $url_hash, | |
$handle_hash); | |
return $this->association_dir. DIRECTORY_SEPARATOR . $filename; | |
} | |
/** | |
* Store an association in the association directory. | |
*/ | |
function storeAssociation($server_url, $association) | |
{ | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return false; | |
} | |
$association_s = $association->serialize(); | |
$filename = $this->getAssociationFilename($server_url, | |
$association->handle); | |
list($tmp_file, $tmp) = $this->_mktemp(); | |
if (!$tmp_file) { | |
trigger_error("_mktemp didn't return a valid file descriptor", | |
E_USER_WARNING); | |
return false; | |
} | |
fwrite($tmp_file, $association_s); | |
fflush($tmp_file); | |
fclose($tmp_file); | |
if (@rename($tmp, $filename)) { | |
return true; | |
} else { | |
// In case we are running on Windows, try unlinking the | |
// file in case it exists. | |
@unlink($filename); | |
// Now the target should not exist. Try renaming again, | |
// giving up if it fails. | |
if (@rename($tmp, $filename)) { | |
return true; | |
} | |
} | |
// If there was an error, don't leave the temporary file | |
// around. | |
Auth_OpenID_FileStore::_removeIfPresent($tmp); | |
return false; | |
} | |
/** | |
* Retrieve an association. If no handle is specified, return the | |
* association with the most recent issue time. | |
* | |
* @return mixed $association | |
*/ | |
function getAssociation($server_url, $handle = null) | |
{ | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return null; | |
} | |
if ($handle === null) { | |
$handle = ''; | |
} | |
// The filename with the empty handle is a prefix of all other | |
// associations for the given server URL. | |
$filename = $this->getAssociationFilename($server_url, $handle); | |
if ($handle) { | |
return $this->_getAssociation($filename); | |
} else { | |
$association_files = | |
Auth_OpenID_FileStore::_listdir($this->association_dir); | |
$matching_files = array(); | |
// strip off the path to do the comparison | |
$name = basename($filename); | |
foreach ($association_files as $association_file) { | |
$base = basename($association_file); | |
if (strpos($base, $name) === 0) { | |
$matching_files[] = $association_file; | |
} | |
} | |
$matching_associations = array(); | |
// read the matching files and sort by time issued | |
foreach ($matching_files as $full_name) { | |
$association = $this->_getAssociation($full_name); | |
if ($association !== null) { | |
$matching_associations[] = array($association->issued, | |
$association); | |
} | |
} | |
$issued = array(); | |
$assocs = array(); | |
foreach ($matching_associations as $key => $assoc) { | |
$issued[$key] = $assoc[0]; | |
$assocs[$key] = $assoc[1]; | |
} | |
array_multisort($issued, SORT_DESC, $assocs, SORT_DESC, | |
$matching_associations); | |
// return the most recently issued one. | |
if ($matching_associations) { | |
list($issued, $assoc) = $matching_associations[0]; | |
return $assoc; | |
} else { | |
return null; | |
} | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _getAssociation($filename) | |
{ | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return null; | |
} | |
$assoc_file = @fopen($filename, 'rb'); | |
if ($assoc_file === false) { | |
return null; | |
} | |
$assoc_s = fread($assoc_file, filesize($filename)); | |
fclose($assoc_file); | |
if (!$assoc_s) { | |
return null; | |
} | |
$association = | |
Auth_OpenID_Association::deserialize('Auth_OpenID_Association', | |
$assoc_s); | |
if (!$association) { | |
Auth_OpenID_FileStore::_removeIfPresent($filename); | |
return null; | |
} | |
if ($association->getExpiresIn() == 0) { | |
Auth_OpenID_FileStore::_removeIfPresent($filename); | |
return null; | |
} else { | |
return $association; | |
} | |
} | |
/** | |
* Remove an association if it exists. Do nothing if it does not. | |
* | |
* @return bool $success | |
*/ | |
function removeAssociation($server_url, $handle) | |
{ | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return null; | |
} | |
$assoc = $this->getAssociation($server_url, $handle); | |
if ($assoc === null) { | |
return false; | |
} else { | |
$filename = $this->getAssociationFilename($server_url, $handle); | |
return Auth_OpenID_FileStore::_removeIfPresent($filename); | |
} | |
} | |
/** | |
* Return whether this nonce is present. As a side effect, mark it | |
* as no longer present. | |
* | |
* @return bool $present | |
*/ | |
function useNonce($server_url, $timestamp, $salt) | |
{ | |
global $Auth_OpenID_SKEW; | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return null; | |
} | |
if ( abs($timestamp - time()) > $Auth_OpenID_SKEW ) { | |
return false; | |
} | |
if ($server_url) { | |
list($proto, $rest) = explode('://', $server_url, 2); | |
} else { | |
$proto = ''; | |
$rest = ''; | |
} | |
$parts = explode('/', $rest, 2); | |
$domain = $this->_filenameEscape($parts[0]); | |
$url_hash = $this->_safe64($server_url); | |
$salt_hash = $this->_safe64($salt); | |
$filename = sprintf('%08x-%s-%s-%s-%s', $timestamp, $proto, | |
$domain, $url_hash, $salt_hash); | |
$filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $filename; | |
$result = @fopen($filename, 'x'); | |
if ($result === false) { | |
return false; | |
} else { | |
fclose($result); | |
return true; | |
} | |
} | |
/** | |
* Remove expired entries from the database. This is potentially | |
* expensive, so only run when it is acceptable to take time. | |
* | |
* @access private | |
*/ | |
function _allAssocs() | |
{ | |
$all_associations = array(); | |
$association_filenames = | |
Auth_OpenID_FileStore::_listdir($this->association_dir); | |
foreach ($association_filenames as $association_filename) { | |
$association_file = fopen($association_filename, 'rb'); | |
if ($association_file !== false) { | |
$assoc_s = fread($association_file, | |
filesize($association_filename)); | |
fclose($association_file); | |
// Remove expired or corrupted associations | |
$association = | |
Auth_OpenID_Association::deserialize( | |
'Auth_OpenID_Association', $assoc_s); | |
if ($association === null) { | |
Auth_OpenID_FileStore::_removeIfPresent( | |
$association_filename); | |
} else { | |
if ($association->getExpiresIn() == 0) { | |
$all_associations[] = array($association_filename, | |
$association); | |
} | |
} | |
} | |
} | |
return $all_associations; | |
} | |
function clean() | |
{ | |
if (!$this->active) { | |
trigger_error("FileStore no longer active", E_USER_ERROR); | |
return null; | |
} | |
$nonces = Auth_OpenID_FileStore::_listdir($this->nonce_dir); | |
$now = time(); | |
// Check all nonces for expiry | |
foreach ($nonces as $nonce) { | |
if (!Auth_OpenID_checkTimestamp($nonce, $now)) { | |
$filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $nonce; | |
Auth_OpenID_FileStore::_removeIfPresent($filename); | |
} | |
} | |
foreach ($this->_allAssocs() as $pair) { | |
list($assoc_filename, $assoc) = $pair; | |
if ($assoc->getExpiresIn() == 0) { | |
Auth_OpenID_FileStore::_removeIfPresent($assoc_filename); | |
} | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _rmtree($dir) | |
{ | |
if ($dir[strlen($dir) - 1] != DIRECTORY_SEPARATOR) { | |
$dir .= DIRECTORY_SEPARATOR; | |
} | |
if ($handle = opendir($dir)) { | |
while ($item = readdir($handle)) { | |
if (!in_array($item, array('.', '..'))) { | |
if (is_dir($dir . $item)) { | |
if (!Auth_OpenID_FileStore::_rmtree($dir . $item)) { | |
return false; | |
} | |
} else if (is_file($dir . $item)) { | |
if (!unlink($dir . $item)) { | |
return false; | |
} | |
} | |
} | |
} | |
closedir($handle); | |
if (!@rmdir($dir)) { | |
return false; | |
} | |
return true; | |
} else { | |
// Couldn't open directory. | |
return false; | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _mkstemp($dir) | |
{ | |
foreach (range(0, 4) as $i) { | |
$name = tempnam($dir, "php_openid_filestore_"); | |
if ($name !== false) { | |
return $name; | |
} | |
} | |
return false; | |
} | |
/** | |
* @access private | |
*/ | |
static function _mkdtemp($dir) | |
{ | |
foreach (range(0, 4) as $i) { | |
$name = $dir . strval(DIRECTORY_SEPARATOR) . strval(getmypid()) . | |
"-" . strval(rand(1, time())); | |
if (!mkdir($name, 0700)) { | |
return false; | |
} else { | |
return $name; | |
} | |
} | |
return false; | |
} | |
/** | |
* @access private | |
*/ | |
function _listdir($dir) | |
{ | |
$handle = opendir($dir); | |
$files = array(); | |
while (false !== ($filename = readdir($handle))) { | |
if (!in_array($filename, array('.', '..'))) { | |
$files[] = $dir . DIRECTORY_SEPARATOR . $filename; | |
} | |
} | |
return $files; | |
} | |
/** | |
* @access private | |
*/ | |
function _isFilenameSafe($char) | |
{ | |
$_Auth_OpenID_filename_allowed = Auth_OpenID_letters . | |
Auth_OpenID_digits . "."; | |
return (strpos($_Auth_OpenID_filename_allowed, $char) !== false); | |
} | |
/** | |
* @access private | |
*/ | |
function _safe64($str) | |
{ | |
$h64 = base64_encode(Auth_OpenID_SHA1($str)); | |
$h64 = str_replace('+', '_', $h64); | |
$h64 = str_replace('/', '.', $h64); | |
$h64 = str_replace('=', '', $h64); | |
return $h64; | |
} | |
/** | |
* @access private | |
*/ | |
function _filenameEscape($str) | |
{ | |
$filename = ""; | |
$b = Auth_OpenID::toBytes($str); | |
for ($i = 0; $i < count($b); $i++) { | |
$c = $b[$i]; | |
if (Auth_OpenID_FileStore::_isFilenameSafe($c)) { | |
$filename .= $c; | |
} else { | |
$filename .= sprintf("_%02X", ord($c)); | |
} | |
} | |
return $filename; | |
} | |
/** | |
* Attempt to remove a file, returning whether the file existed at | |
* the time of the call. | |
* | |
* @access private | |
* @return bool $result True if the file was present, false if not. | |
*/ | |
function _removeIfPresent($filename) | |
{ | |
return @unlink($filename); | |
} | |
function cleanupAssociations() | |
{ | |
$removed = 0; | |
foreach ($this->_allAssocs() as $pair) { | |
list($assoc_filename, $assoc) = $pair; | |
if ($assoc->getExpiresIn() == 0) { | |
$this->_removeIfPresent($assoc_filename); | |
$removed += 1; | |
} | |
} | |
return $removed; | |
} | |
} | |
<?php | |
/** | |
* This is the HMACSHA1 implementation for the OpenID library. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @access private | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
require_once 'Auth/OpenID.php'; | |
/** | |
* SHA1_BLOCKSIZE is this module's SHA1 blocksize used by the fallback | |
* implementation. | |
*/ | |
define('Auth_OpenID_SHA1_BLOCKSIZE', 64); | |
function Auth_OpenID_SHA1($text) | |
{ | |
if (function_exists('hash') && | |
function_exists('hash_algos') && | |
(in_array('sha1', hash_algos()))) { | |
// PHP 5 case (sometimes): 'hash' available and 'sha1' algo | |
// supported. | |
return hash('sha1', $text, true); | |
} else if (function_exists('sha1')) { | |
// PHP 4 case: 'sha1' available. | |
$hex = sha1($text); | |
$raw = ''; | |
for ($i = 0; $i < 40; $i += 2) { | |
$hexcode = substr($hex, $i, 2); | |
$charcode = (int)base_convert($hexcode, 16, 10); | |
$raw .= chr($charcode); | |
} | |
return $raw; | |
} else { | |
// Explode. | |
trigger_error('No SHA1 function found', E_USER_ERROR); | |
} | |
} | |
/** | |
* Compute an HMAC/SHA1 hash. | |
* | |
* @access private | |
* @param string $key The HMAC key | |
* @param string $text The message text to hash | |
* @return string $mac The MAC | |
*/ | |
function Auth_OpenID_HMACSHA1($key, $text) | |
{ | |
if (Auth_OpenID::bytes($key) > Auth_OpenID_SHA1_BLOCKSIZE) { | |
$key = Auth_OpenID_SHA1($key, true); | |
} | |
if (function_exists('hash_hmac') && | |
function_exists('hash_algos') && | |
(in_array('sha1', hash_algos()))) { | |
return hash_hmac('sha1', $text, $key, true); | |
} | |
// Home-made solution | |
$key = str_pad($key, Auth_OpenID_SHA1_BLOCKSIZE, chr(0x00)); | |
$ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE); | |
$opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE); | |
$hash1 = Auth_OpenID_SHA1(($key ^ $ipad) . $text, true); | |
$hmac = Auth_OpenID_SHA1(($key ^ $opad) . $hash1, true); | |
return $hmac; | |
} | |
if (function_exists('hash') && | |
function_exists('hash_algos') && | |
(in_array('sha256', hash_algos()))) { | |
function Auth_OpenID_SHA256($text) | |
{ | |
// PHP 5 case: 'hash' available and 'sha256' algo supported. | |
return hash('sha256', $text, true); | |
} | |
define('Auth_OpenID_SHA256_SUPPORTED', true); | |
} else { | |
define('Auth_OpenID_SHA256_SUPPORTED', false); | |
} | |
if (function_exists('hash_hmac') && | |
function_exists('hash_algos') && | |
(in_array('sha256', hash_algos()))) { | |
function Auth_OpenID_HMACSHA256($key, $text) | |
{ | |
// Return raw MAC (not hex string). | |
return hash_hmac('sha256', $text, $key, true); | |
} | |
define('Auth_OpenID_HMACSHA256_SUPPORTED', true); | |
} else { | |
define('Auth_OpenID_HMACSHA256_SUPPORTED', false); | |
} | |
<?php | |
/** | |
* This file specifies the interface for PHP OpenID store implementations. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* This is the interface for the store objects the OpenID library | |
* uses. It is a single class that provides all of the persistence | |
* mechanisms that the OpenID library needs, for both servers and | |
* consumers. If you want to create an SQL-driven store, please see | |
* then {@link Auth_OpenID_SQLStore} class. | |
* | |
* Change: Version 2.0 removed the storeNonce, getAuthKey, and isDumb | |
* methods, and changed the behavior of the useNonce method to support | |
* one-way nonces. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
*/ | |
class Auth_OpenID_OpenIDStore { | |
/** | |
* This method puts an Association object into storage, | |
* retrievable by server URL and handle. | |
* | |
* @param string $server_url The URL of the identity server that | |
* this association is with. Because of the way the server portion | |
* of the library uses this interface, don't assume there are any | |
* limitations on the character set of the input string. In | |
* particular, expect to see unescaped non-url-safe characters in | |
* the server_url field. | |
* | |
* @param Association $association The Association to store. | |
*/ | |
function storeAssociation($server_url, $association) | |
{ | |
trigger_error("Auth_OpenID_OpenIDStore::storeAssociation ". | |
"not implemented", E_USER_ERROR); | |
} | |
/* | |
* Remove expired nonces from the store. | |
* | |
* Discards any nonce from storage that is old enough that its | |
* timestamp would not pass useNonce(). | |
* | |
* This method is not called in the normal operation of the | |
* library. It provides a way for store admins to keep their | |
* storage from filling up with expired data. | |
* | |
* @return the number of nonces expired | |
*/ | |
function cleanupNonces() | |
{ | |
trigger_error("Auth_OpenID_OpenIDStore::cleanupNonces ". | |
"not implemented", E_USER_ERROR); | |
} | |
/* | |
* Remove expired associations from the store. | |
* | |
* This method is not called in the normal operation of the | |
* library. It provides a way for store admins to keep their | |
* storage from filling up with expired data. | |
* | |
* @return the number of associations expired. | |
*/ | |
function cleanupAssociations() | |
{ | |
trigger_error("Auth_OpenID_OpenIDStore::cleanupAssociations ". | |
"not implemented", E_USER_ERROR); | |
} | |
/* | |
* Shortcut for cleanupNonces(), cleanupAssociations(). | |
* | |
* This method is not called in the normal operation of the | |
* library. It provides a way for store admins to keep their | |
* storage from filling up with expired data. | |
*/ | |
function cleanup() | |
{ | |
return array($this->cleanupNonces(), | |
$this->cleanupAssociations()); | |
} | |
/** | |
* Report whether this storage supports cleanup | |
*/ | |
function supportsCleanup() | |
{ | |
return true; | |
} | |
/** | |
* This method returns an Association object from storage that | |
* matches the server URL and, if specified, handle. It returns | |
* null if no such association is found or if the matching | |
* association is expired. | |
* | |
* If no handle is specified, the store may return any association | |
* which matches the server URL. If multiple associations are | |
* valid, the recommended return value for this method is the one | |
* most recently issued. | |
* | |
* This method is allowed (and encouraged) to garbage collect | |
* expired associations when found. This method must not return | |
* expired associations. | |
* | |
* @param string $server_url The URL of the identity server to get | |
* the association for. Because of the way the server portion of | |
* the library uses this interface, don't assume there are any | |
* limitations on the character set of the input string. In | |
* particular, expect to see unescaped non-url-safe characters in | |
* the server_url field. | |
* | |
* @param mixed $handle This optional parameter is the handle of | |
* the specific association to get. If no specific handle is | |
* provided, any valid association matching the server URL is | |
* returned. | |
* | |
* @return Association The Association for the given identity | |
* server. | |
*/ | |
function getAssociation($server_url, $handle = null) | |
{ | |
trigger_error("Auth_OpenID_OpenIDStore::getAssociation ". | |
"not implemented", E_USER_ERROR); | |
} | |
/** | |
* This method removes the matching association if it's found, and | |
* returns whether the association was removed or not. | |
* | |
* @param string $server_url The URL of the identity server the | |
* association to remove belongs to. Because of the way the server | |
* portion of the library uses this interface, don't assume there | |
* are any limitations on the character set of the input | |
* string. In particular, expect to see unescaped non-url-safe | |
* characters in the server_url field. | |
* | |
* @param string $handle This is the handle of the association to | |
* remove. If there isn't an association found that matches both | |
* the given URL and handle, then there was no matching handle | |
* found. | |
* | |
* @return mixed Returns whether or not the given association existed. | |
*/ | |
function removeAssociation($server_url, $handle) | |
{ | |
trigger_error("Auth_OpenID_OpenIDStore::removeAssociation ". | |
"not implemented", E_USER_ERROR); | |
} | |
/** | |
* Called when using a nonce. | |
* | |
* This method should return C{True} if the nonce has not been | |
* used before, and store it for a while to make sure nobody | |
* tries to use the same value again. If the nonce has already | |
* been used, return C{False}. | |
* | |
* Change: In earlier versions, round-trip nonces were used and a | |
* nonce was only valid if it had been previously stored with | |
* storeNonce. Version 2.0 uses one-way nonces, requiring a | |
* different implementation here that does not depend on a | |
* storeNonce call. (storeNonce is no longer part of the | |
* interface. | |
* | |
* @param string $nonce The nonce to use. | |
* | |
* @return bool Whether or not the nonce was valid. | |
*/ | |
function useNonce($server_url, $timestamp, $salt) | |
{ | |
trigger_error("Auth_OpenID_OpenIDStore::useNonce ". | |
"not implemented", E_USER_ERROR); | |
} | |
/** | |
* Removes all entries from the store; implementation is optional. | |
*/ | |
function reset() | |
{ | |
} | |
} | |
<?php | |
/** | |
* OpenID protocol key-value/comma-newline format parsing and | |
* serialization | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @access private | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Container for key-value/comma-newline OpenID format and parsing | |
*/ | |
class Auth_OpenID_KVForm { | |
/** | |
* Convert an OpenID colon/newline separated string into an | |
* associative array | |
* | |
* @static | |
* @access private | |
*/ | |
static function toArray($kvs, $strict=false) | |
{ | |
$lines = explode("\n", $kvs); | |
$last = array_pop($lines); | |
if ($last !== '') { | |
array_push($lines, $last); | |
if ($strict) { | |
return false; | |
} | |
} | |
$values = array(); | |
for ($lineno = 0; $lineno < count($lines); $lineno++) { | |
$line = $lines[$lineno]; | |
$kv = explode(':', $line, 2); | |
if (count($kv) != 2) { | |
if ($strict) { | |
return false; | |
} | |
continue; | |
} | |
$key = $kv[0]; | |
$tkey = trim($key); | |
if ($tkey != $key) { | |
if ($strict) { | |
return false; | |
} | |
} | |
$value = $kv[1]; | |
$tval = trim($value); | |
if ($tval != $value) { | |
if ($strict) { | |
return false; | |
} | |
} | |
$values[$tkey] = $tval; | |
} | |
return $values; | |
} | |
/** | |
* Convert an array into an OpenID colon/newline separated string | |
* | |
* @static | |
* @access private | |
*/ | |
static function fromArray($values) | |
{ | |
if ($values === null) { | |
return null; | |
} | |
ksort($values); | |
$serialized = ''; | |
foreach ($values as $key => $value) { | |
if (is_array($value)) { | |
list($key, $value) = array($value[0], $value[1]); | |
} | |
if (strpos($key, ':') !== false) { | |
return null; | |
} | |
if (strpos($key, "\n") !== false) { | |
return null; | |
} | |
if (strpos($value, "\n") !== false) { | |
return null; | |
} | |
$serialized .= "$key:$value\n"; | |
} | |
return $serialized; | |
} | |
} | |
<?php | |
/** | |
* SQL-backed OpenID stores for use with PEAR::MDB2. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005 Janrain, Inc. | |
* @license http://www.gnu.org/copyleft/lesser.html LGPL | |
*/ | |
require_once 'MDB2.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/Interface.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/Nonce.php'; | |
/** | |
* This store uses a PEAR::MDB2 connection to store persistence | |
* information. | |
* | |
* The table names used are determined by the class variables | |
* associations_table_name and nonces_table_name. To change the name | |
* of the tables used, pass new table names into the constructor. | |
* | |
* To create the tables with the proper schema, see the createTables | |
* method. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_MDB2Store extends Auth_OpenID_OpenIDStore { | |
/** | |
* This creates a new MDB2Store instance. It requires an | |
* established database connection be given to it, and it allows | |
* overriding the default table names. | |
* | |
* @param connection $connection This must be an established | |
* connection to a database of the correct type for the SQLStore | |
* subclass you're using. This must be a PEAR::MDB2 connection | |
* handle. | |
* | |
* @param associations_table: This is an optional parameter to | |
* specify the name of the table used for storing associations. | |
* The default value is 'oid_associations'. | |
* | |
* @param nonces_table: This is an optional parameter to specify | |
* the name of the table used for storing nonces. The default | |
* value is 'oid_nonces'. | |
*/ | |
function Auth_OpenID_MDB2Store($connection, | |
$associations_table = null, | |
$nonces_table = null) | |
{ | |
$this->associations_table_name = "oid_associations"; | |
$this->nonces_table_name = "oid_nonces"; | |
// Check the connection object type to be sure it's a PEAR | |
// database connection. | |
if (!is_object($connection) || | |
!is_subclass_of($connection, 'mdb2_driver_common')) { | |
trigger_error("Auth_OpenID_MDB2Store expected PEAR connection " . | |
"object (got ".get_class($connection).")", | |
E_USER_ERROR); | |
return; | |
} | |
$this->connection = $connection; | |
// Be sure to set the fetch mode so the results are keyed on | |
// column name instead of column index. | |
$this->connection->setFetchMode(MDB2_FETCHMODE_ASSOC); | |
if (PEAR::isError($this->connection->loadModule('Extended'))) { | |
trigger_error("Unable to load MDB2_Extended module", E_USER_ERROR); | |
return; | |
} | |
if ($associations_table) { | |
$this->associations_table_name = $associations_table; | |
} | |
if ($nonces_table) { | |
$this->nonces_table_name = $nonces_table; | |
} | |
$this->max_nonce_age = 6 * 60 * 60; | |
} | |
function tableExists($table_name) | |
{ | |
return !PEAR::isError($this->connection->query( | |
sprintf("SELECT * FROM %s LIMIT 0", | |
$table_name))); | |
} | |
function createTables() | |
{ | |
$n = $this->create_nonce_table(); | |
$a = $this->create_assoc_table(); | |
if (!$n || !$a) { | |
return false; | |
} | |
return true; | |
} | |
function create_nonce_table() | |
{ | |
if (!$this->tableExists($this->nonces_table_name)) { | |
switch ($this->connection->phptype) { | |
case "mysql": | |
case "mysqli": | |
// Custom SQL for MySQL to use InnoDB and variable- | |
// length keys | |
$r = $this->connection->exec( | |
sprintf("CREATE TABLE %s (\n". | |
" server_url VARCHAR(2047) NOT NULL DEFAULT '',\n". | |
" timestamp INTEGER NOT NULL,\n". | |
" salt CHAR(40) NOT NULL,\n". | |
" UNIQUE (server_url(255), timestamp, salt)\n". | |
") TYPE=InnoDB", | |
$this->nonces_table_name)); | |
if (PEAR::isError($r)) { | |
return false; | |
} | |
break; | |
default: | |
if (PEAR::isError( | |
$this->connection->loadModule('Manager'))) { | |
return false; | |
} | |
$fields = array( | |
"server_url" => array( | |
"type" => "text", | |
"length" => 2047, | |
"notnull" => true | |
), | |
"timestamp" => array( | |
"type" => "integer", | |
"notnull" => true | |
), | |
"salt" => array( | |
"type" => "text", | |
"length" => 40, | |
"fixed" => true, | |
"notnull" => true | |
) | |
); | |
$constraint = array( | |
"unique" => 1, | |
"fields" => array( | |
"server_url" => true, | |
"timestamp" => true, | |
"salt" => true | |
) | |
); | |
$r = $this->connection->createTable($this->nonces_table_name, | |
$fields); | |
if (PEAR::isError($r)) { | |
return false; | |
} | |
$r = $this->connection->createConstraint( | |
$this->nonces_table_name, | |
$this->nonces_table_name . "_constraint", | |
$constraint); | |
if (PEAR::isError($r)) { | |
return false; | |
} | |
break; | |
} | |
} | |
return true; | |
} | |
function create_assoc_table() | |
{ | |
if (!$this->tableExists($this->associations_table_name)) { | |
switch ($this->connection->phptype) { | |
case "mysql": | |
case "mysqli": | |
// Custom SQL for MySQL to use InnoDB and variable- | |
// length keys | |
$r = $this->connection->exec( | |
sprintf("CREATE TABLE %s(\n". | |
" server_url VARCHAR(2047) NOT NULL DEFAULT '',\n". | |
" handle VARCHAR(255) NOT NULL,\n". | |
" secret BLOB NOT NULL,\n". | |
" issued INTEGER NOT NULL,\n". | |
" lifetime INTEGER NOT NULL,\n". | |
" assoc_type VARCHAR(64) NOT NULL,\n". | |
" PRIMARY KEY (server_url(255), handle)\n". | |
") TYPE=InnoDB", | |
$this->associations_table_name)); | |
if (PEAR::isError($r)) { | |
return false; | |
} | |
break; | |
default: | |
if (PEAR::isError( | |
$this->connection->loadModule('Manager'))) { | |
return false; | |
} | |
$fields = array( | |
"server_url" => array( | |
"type" => "text", | |
"length" => 2047, | |
"notnull" => true | |
), | |
"handle" => array( | |
"type" => "text", | |
"length" => 255, | |
"notnull" => true | |
), | |
"secret" => array( | |
"type" => "blob", | |
"length" => "255", | |
"notnull" => true | |
), | |
"issued" => array( | |
"type" => "integer", | |
"notnull" => true | |
), | |
"lifetime" => array( | |
"type" => "integer", | |
"notnull" => true | |
), | |
"assoc_type" => array( | |
"type" => "text", | |
"length" => 64, | |
"notnull" => true | |
) | |
); | |
$options = array( | |
"primary" => array( | |
"server_url" => true, | |
"handle" => true | |
) | |
); | |
$r = $this->connection->createTable( | |
$this->associations_table_name, | |
$fields, | |
$options); | |
if (PEAR::isError($r)) { | |
return false; | |
} | |
break; | |
} | |
} | |
return true; | |
} | |
function storeAssociation($server_url, $association) | |
{ | |
$fields = array( | |
"server_url" => array( | |
"value" => $server_url, | |
"key" => true | |
), | |
"handle" => array( | |
"value" => $association->handle, | |
"key" => true | |
), | |
"secret" => array( | |
"value" => $association->secret, | |
"type" => "blob" | |
), | |
"issued" => array( | |
"value" => $association->issued | |
), | |
"lifetime" => array( | |
"value" => $association->lifetime | |
), | |
"assoc_type" => array( | |
"value" => $association->assoc_type | |
) | |
); | |
return !PEAR::isError($this->connection->replace( | |
$this->associations_table_name, | |
$fields)); | |
} | |
function cleanupNonces() | |
{ | |
global $Auth_OpenID_SKEW; | |
$v = time() - $Auth_OpenID_SKEW; | |
return $this->connection->exec( | |
sprintf("DELETE FROM %s WHERE timestamp < %d", | |
$this->nonces_table_name, $v)); | |
} | |
function cleanupAssociations() | |
{ | |
return $this->connection->exec( | |
sprintf("DELETE FROM %s WHERE issued + lifetime < %d", | |
$this->associations_table_name, time())); | |
} | |
function getAssociation($server_url, $handle = null) | |
{ | |
$sql = ""; | |
$params = null; | |
$types = array( | |
"text", | |
"blob", | |
"integer", | |
"integer", | |
"text" | |
); | |
if ($handle !== null) { | |
$sql = sprintf("SELECT handle, secret, issued, lifetime, assoc_type " . | |
"FROM %s WHERE server_url = ? AND handle = ?", | |
$this->associations_table_name); | |
$params = array($server_url, $handle); | |
} else { | |
$sql = sprintf("SELECT handle, secret, issued, lifetime, assoc_type " . | |
"FROM %s WHERE server_url = ? ORDER BY issued DESC", | |
$this->associations_table_name); | |
$params = array($server_url); | |
} | |
$assoc = $this->connection->getRow($sql, $types, $params); | |
if (!$assoc || PEAR::isError($assoc)) { | |
return null; | |
} else { | |
$association = new Auth_OpenID_Association($assoc['handle'], | |
stream_get_contents( | |
$assoc['secret']), | |
$assoc['issued'], | |
$assoc['lifetime'], | |
$assoc['assoc_type']); | |
fclose($assoc['secret']); | |
return $association; | |
} | |
} | |
function removeAssociation($server_url, $handle) | |
{ | |
$r = $this->connection->execParam( | |
sprintf("DELETE FROM %s WHERE server_url = ? AND handle = ?", | |
$this->associations_table_name), | |
array($server_url, $handle)); | |
if (PEAR::isError($r) || $r == 0) { | |
return false; | |
} | |
return true; | |
} | |
function useNonce($server_url, $timestamp, $salt) | |
{ | |
global $Auth_OpenID_SKEW; | |
if (abs($timestamp - time()) > $Auth_OpenID_SKEW ) { | |
return false; | |
} | |
$fields = array( | |
"timestamp" => $timestamp, | |
"salt" => $salt | |
); | |
if (!empty($server_url)) { | |
$fields["server_url"] = $server_url; | |
} | |
$r = $this->connection->autoExecute( | |
$this->nonces_table_name, | |
$fields, | |
MDB2_AUTOQUERY_INSERT); | |
if (PEAR::isError($r)) { | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Resets the store by removing all records from the store's | |
* tables. | |
*/ | |
function reset() | |
{ | |
$this->connection->query(sprintf("DELETE FROM %s", | |
$this->associations_table_name)); | |
$this->connection->query(sprintf("DELETE FROM %s", | |
$this->nonces_table_name)); | |
} | |
} | |
?> | |
<?php | |
/** | |
* This file supplies a memcached store backend for OpenID servers and | |
* consumers. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author Artemy Tregubenko <me@arty.name> | |
* @copyright 2008 JanRain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
* Contributed by Open Web Technologies <http://openwebtech.ru/> | |
*/ | |
/** | |
* Import the interface for creating a new store class. | |
*/ | |
require_once 'Auth/OpenID/Interface.php'; | |
/** | |
* This is a memcached-based store for OpenID associations and | |
* nonces. | |
* | |
* As memcache has limit of 250 chars for key length, | |
* server_url, handle and salt are hashed with sha1(). | |
* | |
* Most of the methods of this class are implementation details. | |
* People wishing to just use this store need only pay attention to | |
* the constructor. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_MemcachedStore extends Auth_OpenID_OpenIDStore { | |
/** | |
* Initializes a new {@link Auth_OpenID_MemcachedStore} instance. | |
* Just saves memcached object as property. | |
* | |
* @param resource connection Memcache connection resourse | |
*/ | |
function Auth_OpenID_MemcachedStore($connection, $compress = false) | |
{ | |
$this->connection = $connection; | |
$this->compress = $compress ? MEMCACHE_COMPRESSED : 0; | |
} | |
/** | |
* Store association until its expiration time in memcached. | |
* Overwrites any existing association with same server_url and | |
* handle. Handles list of associations for every server. | |
*/ | |
function storeAssociation($server_url, $association) | |
{ | |
// create memcached keys for association itself | |
// and list of associations for this server | |
$associationKey = $this->associationKey($server_url, | |
$association->handle); | |
$serverKey = $this->associationServerKey($server_url); | |
// get list of associations | |
$serverAssociations = $this->connection->get($serverKey); | |
// if no such list, initialize it with empty array | |
if (!$serverAssociations) { | |
$serverAssociations = array(); | |
} | |
// and store given association key in it | |
$serverAssociations[$association->issued] = $associationKey; | |
// save associations' keys list | |
$this->connection->set( | |
$serverKey, | |
$serverAssociations, | |
$this->compress | |
); | |
// save association itself | |
$this->connection->set( | |
$associationKey, | |
$association, | |
$this->compress, | |
$association->issued + $association->lifetime); | |
} | |
/** | |
* Read association from memcached. If no handle given | |
* and multiple associations found, returns latest issued | |
*/ | |
function getAssociation($server_url, $handle = null) | |
{ | |
// simple case: handle given | |
if ($handle !== null) { | |
// get association, return null if failed | |
$association = $this->connection->get( | |
$this->associationKey($server_url, $handle)); | |
return $association ? $association : null; | |
} | |
// no handle given, working with list | |
// create key for list of associations | |
$serverKey = $this->associationServerKey($server_url); | |
// get list of associations | |
$serverAssociations = $this->connection->get($serverKey); | |
// return null if failed or got empty list | |
if (!$serverAssociations) { | |
return null; | |
} | |
// get key of most recently issued association | |
$keys = array_keys($serverAssociations); | |
sort($keys); | |
$lastKey = $serverAssociations[array_pop($keys)]; | |
// get association, return null if failed | |
$association = $this->connection->get($lastKey); | |
return $association ? $association : null; | |
} | |
/** | |
* Immediately delete association from memcache. | |
*/ | |
function removeAssociation($server_url, $handle) | |
{ | |
// create memcached keys for association itself | |
// and list of associations for this server | |
$serverKey = $this->associationServerKey($server_url); | |
$associationKey = $this->associationKey($server_url, | |
$handle); | |
// get list of associations | |
$serverAssociations = $this->connection->get($serverKey); | |
// return null if failed or got empty list | |
if (!$serverAssociations) { | |
return false; | |
} | |
// ensure that given association key exists in list | |
$serverAssociations = array_flip($serverAssociations); | |
if (!array_key_exists($associationKey, $serverAssociations)) { | |
return false; | |
} | |
// remove given association key from list | |
unset($serverAssociations[$associationKey]); | |
$serverAssociations = array_flip($serverAssociations); | |
// save updated list | |
$this->connection->set( | |
$serverKey, | |
$serverAssociations, | |
$this->compress | |
); | |
// delete association | |
return $this->connection->delete($associationKey); | |
} | |
/** | |
* Create nonce for server and salt, expiring after | |
* $Auth_OpenID_SKEW seconds. | |
*/ | |
function useNonce($server_url, $timestamp, $salt) | |
{ | |
global $Auth_OpenID_SKEW; | |
// save one request to memcache when nonce obviously expired | |
if (abs($timestamp - time()) > $Auth_OpenID_SKEW) { | |
return false; | |
} | |
// returns false when nonce already exists | |
// otherwise adds nonce | |
return $this->connection->add( | |
'openid_nonce_' . sha1($server_url) . '_' . sha1($salt), | |
1, // any value here | |
$this->compress, | |
$Auth_OpenID_SKEW); | |
} | |
/** | |
* Memcache key is prefixed with 'openid_association_' string. | |
*/ | |
function associationKey($server_url, $handle = null) | |
{ | |
return 'openid_association_' . sha1($server_url) . '_' . sha1($handle); | |
} | |
/** | |
* Memcache key is prefixed with 'openid_association_' string. | |
*/ | |
function associationServerKey($server_url) | |
{ | |
return 'openid_association_server_' . sha1($server_url); | |
} | |
/** | |
* Report that this storage doesn't support cleanup | |
*/ | |
function supportsCleanup() | |
{ | |
return false; | |
} | |
} | |
<?php | |
/** | |
* Extension argument processing code | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Import tools needed to deal with messages. | |
*/ | |
require_once 'Auth/OpenID.php'; | |
require_once 'Auth/OpenID/KVForm.php'; | |
require_once 'Auth/Yadis/XML.php'; | |
require_once 'Auth/OpenID/Consumer.php'; // For Auth_OpenID_FailureResponse | |
// This doesn't REALLY belong here, but where is better? | |
define('Auth_OpenID_IDENTIFIER_SELECT', | |
"http://specs.openid.net/auth/2.0/identifier_select"); | |
// URI for Simple Registration extension, the only commonly deployed | |
// OpenID 1.x extension, and so a special case | |
define('Auth_OpenID_SREG_URI', 'http://openid.net/sreg/1.0'); | |
// The OpenID 1.X namespace URI | |
define('Auth_OpenID_OPENID1_NS', 'http://openid.net/signon/1.0'); | |
define('Auth_OpenID_THE_OTHER_OPENID1_NS', 'http://openid.net/signon/1.1'); | |
function Auth_OpenID_isOpenID1($ns) | |
{ | |
return ($ns == Auth_OpenID_THE_OTHER_OPENID1_NS) || | |
($ns == Auth_OpenID_OPENID1_NS); | |
} | |
// The OpenID 2.0 namespace URI | |
define('Auth_OpenID_OPENID2_NS', 'http://specs.openid.net/auth/2.0'); | |
// The namespace consisting of pairs with keys that are prefixed with | |
// "openid." but not in another namespace. | |
define('Auth_OpenID_NULL_NAMESPACE', 'Null namespace'); | |
// The null namespace, when it is an allowed OpenID namespace | |
define('Auth_OpenID_OPENID_NS', 'OpenID namespace'); | |
// The top-level namespace, excluding all pairs with keys that start | |
// with "openid." | |
define('Auth_OpenID_BARE_NS', 'Bare namespace'); | |
// Sentinel for Message implementation to indicate that getArg should | |
// return null instead of returning a default. | |
define('Auth_OpenID_NO_DEFAULT', 'NO DEFAULT ALLOWED'); | |
// Limit, in bytes, of identity provider and return_to URLs, including | |
// response payload. See OpenID 1.1 specification, Appendix D. | |
define('Auth_OpenID_OPENID1_URL_LIMIT', 2047); | |
// All OpenID protocol fields. Used to check namespace aliases. | |
global $Auth_OpenID_OPENID_PROTOCOL_FIELDS; | |
$Auth_OpenID_OPENID_PROTOCOL_FIELDS = array( | |
'ns', 'mode', 'error', 'return_to', 'contact', 'reference', | |
'signed', 'assoc_type', 'session_type', 'dh_modulus', 'dh_gen', | |
'dh_consumer_public', 'claimed_id', 'identity', 'realm', | |
'invalidate_handle', 'op_endpoint', 'response_nonce', 'sig', | |
'assoc_handle', 'trust_root', 'openid'); | |
// Global namespace / alias registration map. See | |
// Auth_OpenID_registerNamespaceAlias. | |
global $Auth_OpenID_registered_aliases; | |
$Auth_OpenID_registered_aliases = array(); | |
/** | |
* Registers a (namespace URI, alias) mapping in a global namespace | |
* alias map. Raises NamespaceAliasRegistrationError if either the | |
* namespace URI or alias has already been registered with a different | |
* value. This function is required if you want to use a namespace | |
* with an OpenID 1 message. | |
*/ | |
function Auth_OpenID_registerNamespaceAlias($namespace_uri, $alias) | |
{ | |
global $Auth_OpenID_registered_aliases; | |
if (Auth_OpenID::arrayGet($Auth_OpenID_registered_aliases, | |
$alias) == $namespace_uri) { | |
return true; | |
} | |
if (in_array($namespace_uri, | |
array_values($Auth_OpenID_registered_aliases))) { | |
return false; | |
} | |
if (in_array($alias, array_keys($Auth_OpenID_registered_aliases))) { | |
return false; | |
} | |
$Auth_OpenID_registered_aliases[$alias] = $namespace_uri; | |
return true; | |
} | |
/** | |
* Removes a (namespace_uri, alias) registration from the global | |
* namespace alias map. Returns true if the removal succeeded; false | |
* if not (if the mapping did not exist). | |
*/ | |
function Auth_OpenID_removeNamespaceAlias($namespace_uri, $alias) | |
{ | |
global $Auth_OpenID_registered_aliases; | |
if (Auth_OpenID::arrayGet($Auth_OpenID_registered_aliases, | |
$alias) === $namespace_uri) { | |
unset($Auth_OpenID_registered_aliases[$alias]); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* An Auth_OpenID_Mapping maintains a mapping from arbitrary keys to | |
* arbitrary values. (This is unlike an ordinary PHP array, whose | |
* keys may be only simple scalars.) | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_Mapping { | |
/** | |
* Initialize a mapping. If $classic_array is specified, its keys | |
* and values are used to populate the mapping. | |
*/ | |
function Auth_OpenID_Mapping($classic_array = null) | |
{ | |
$this->keys = array(); | |
$this->values = array(); | |
if (is_array($classic_array)) { | |
foreach ($classic_array as $key => $value) { | |
$this->set($key, $value); | |
} | |
} | |
} | |
/** | |
* Returns true if $thing is an Auth_OpenID_Mapping object; false | |
* if not. | |
*/ | |
static function isA($thing) | |
{ | |
return (is_object($thing) && | |
strtolower(get_class($thing)) == 'auth_openid_mapping'); | |
} | |
/** | |
* Returns an array of the keys in the mapping. | |
*/ | |
function keys() | |
{ | |
return $this->keys; | |
} | |
/** | |
* Returns an array of values in the mapping. | |
*/ | |
function values() | |
{ | |
return $this->values; | |
} | |
/** | |
* Returns an array of (key, value) pairs in the mapping. | |
*/ | |
function items() | |
{ | |
$temp = array(); | |
for ($i = 0; $i < count($this->keys); $i++) { | |
$temp[] = array($this->keys[$i], | |
$this->values[$i]); | |
} | |
return $temp; | |
} | |
/** | |
* Returns the "length" of the mapping, or the number of keys. | |
*/ | |
function len() | |
{ | |
return count($this->keys); | |
} | |
/** | |
* Sets a key-value pair in the mapping. If the key already | |
* exists, its value is replaced with the new value. | |
*/ | |
function set($key, $value) | |
{ | |
$index = array_search($key, $this->keys); | |
if ($index !== false) { | |
$this->values[$index] = $value; | |
} else { | |
$this->keys[] = $key; | |
$this->values[] = $value; | |
} | |
} | |
/** | |
* Gets a specified value from the mapping, associated with the | |
* specified key. If the key does not exist in the mapping, | |
* $default is returned instead. | |
*/ | |
function get($key, $default = null) | |
{ | |
$index = array_search($key, $this->keys); | |
if ($index !== false) { | |
return $this->values[$index]; | |
} else { | |
return $default; | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _reflow() | |
{ | |
// PHP is broken yet again. Sort the arrays to remove the | |
// hole in the numeric indexes that make up the array. | |
$old_keys = $this->keys; | |
$old_values = $this->values; | |
$this->keys = array(); | |
$this->values = array(); | |
foreach ($old_keys as $k) { | |
$this->keys[] = $k; | |
} | |
foreach ($old_values as $v) { | |
$this->values[] = $v; | |
} | |
} | |
/** | |
* Deletes a key-value pair from the mapping with the specified | |
* key. | |
*/ | |
function del($key) | |
{ | |
$index = array_search($key, $this->keys); | |
if ($index !== false) { | |
unset($this->keys[$index]); | |
unset($this->values[$index]); | |
$this->_reflow(); | |
return true; | |
} | |
return false; | |
} | |
/** | |
* Returns true if the specified value has a key in the mapping; | |
* false if not. | |
*/ | |
function contains($value) | |
{ | |
return (array_search($value, $this->keys) !== false); | |
} | |
} | |
/** | |
* Maintains a bijective map between namespace uris and aliases. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_NamespaceMap { | |
function Auth_OpenID_NamespaceMap() | |
{ | |
$this->alias_to_namespace = new Auth_OpenID_Mapping(); | |
$this->namespace_to_alias = new Auth_OpenID_Mapping(); | |
$this->implicit_namespaces = array(); | |
} | |
function getAlias($namespace_uri) | |
{ | |
return $this->namespace_to_alias->get($namespace_uri); | |
} | |
function getNamespaceURI($alias) | |
{ | |
return $this->alias_to_namespace->get($alias); | |
} | |
function iterNamespaceURIs() | |
{ | |
// Return an iterator over the namespace URIs | |
return $this->namespace_to_alias->keys(); | |
} | |
function iterAliases() | |
{ | |
// Return an iterator over the aliases""" | |
return $this->alias_to_namespace->keys(); | |
} | |
function iteritems() | |
{ | |
return $this->namespace_to_alias->items(); | |
} | |
function isImplicit($namespace_uri) | |
{ | |
return in_array($namespace_uri, $this->implicit_namespaces); | |
} | |
function addAlias($namespace_uri, $desired_alias, $implicit=false) | |
{ | |
// Add an alias from this namespace URI to the desired alias | |
global $Auth_OpenID_OPENID_PROTOCOL_FIELDS; | |
// Check that desired_alias is not an openid protocol field as | |
// per the spec. | |
if (in_array($desired_alias, $Auth_OpenID_OPENID_PROTOCOL_FIELDS)) { | |
Auth_OpenID::log("\"%s\" is not an allowed namespace alias", | |
$desired_alias); | |
return null; | |
} | |
// Check that desired_alias does not contain a period as per | |
// the spec. | |
if (strpos($desired_alias, '.') !== false) { | |
Auth_OpenID::log('"%s" must not contain a dot', $desired_alias); | |
return null; | |
} | |
// Check that there is not a namespace already defined for the | |
// desired alias | |
$current_namespace_uri = | |
$this->alias_to_namespace->get($desired_alias); | |
if (($current_namespace_uri !== null) && | |
($current_namespace_uri != $namespace_uri)) { | |
Auth_OpenID::log('Cannot map "%s" because previous mapping exists', | |
$namespace_uri); | |
return null; | |
} | |
// Check that there is not already a (different) alias for | |
// this namespace URI | |
$alias = $this->namespace_to_alias->get($namespace_uri); | |
if (($alias !== null) && ($alias != $desired_alias)) { | |
Auth_OpenID::log('Cannot map %s to alias %s. ' . | |
'It is already mapped to alias %s', | |
$namespace_uri, $desired_alias, $alias); | |
return null; | |
} | |
assert((Auth_OpenID_NULL_NAMESPACE === $desired_alias) || | |
is_string($desired_alias)); | |
$this->alias_to_namespace->set($desired_alias, $namespace_uri); | |
$this->namespace_to_alias->set($namespace_uri, $desired_alias); | |
if ($implicit) { | |
array_push($this->implicit_namespaces, $namespace_uri); | |
} | |
return $desired_alias; | |
} | |
function add($namespace_uri) | |
{ | |
// Add this namespace URI to the mapping, without caring what | |
// alias it ends up with | |
// See if this namespace is already mapped to an alias | |
$alias = $this->namespace_to_alias->get($namespace_uri); | |
if ($alias !== null) { | |
return $alias; | |
} | |
// Fall back to generating a numerical alias | |
$i = 0; | |
while (1) { | |
$alias = 'ext' . strval($i); | |
if ($this->addAlias($namespace_uri, $alias) === null) { | |
$i += 1; | |
} else { | |
return $alias; | |
} | |
} | |
// Should NEVER be reached! | |
return null; | |
} | |
function contains($namespace_uri) | |
{ | |
return $this->isDefined($namespace_uri); | |
} | |
function isDefined($namespace_uri) | |
{ | |
return $this->namespace_to_alias->contains($namespace_uri); | |
} | |
} | |
/** | |
* In the implementation of this object, null represents the global | |
* namespace as well as a namespace with no key. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_Message { | |
function Auth_OpenID_Message($openid_namespace = null) | |
{ | |
// Create an empty Message | |
$this->allowed_openid_namespaces = array( | |
Auth_OpenID_OPENID1_NS, | |
Auth_OpenID_THE_OTHER_OPENID1_NS, | |
Auth_OpenID_OPENID2_NS); | |
$this->args = new Auth_OpenID_Mapping(); | |
$this->namespaces = new Auth_OpenID_NamespaceMap(); | |
if ($openid_namespace === null) { | |
$this->_openid_ns_uri = null; | |
} else { | |
$implicit = Auth_OpenID_isOpenID1($openid_namespace); | |
$this->setOpenIDNamespace($openid_namespace, $implicit); | |
} | |
} | |
function isOpenID1() | |
{ | |
return Auth_OpenID_isOpenID1($this->getOpenIDNamespace()); | |
} | |
function isOpenID2() | |
{ | |
return $this->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS; | |
} | |
static function fromPostArgs($args) | |
{ | |
// Construct a Message containing a set of POST arguments | |
$obj = new Auth_OpenID_Message(); | |
// Partition into "openid." args and bare args | |
$openid_args = array(); | |
foreach ($args as $key => $value) { | |
if (is_array($value)) { | |
return null; | |
} | |
$parts = explode('.', $key, 2); | |
if (count($parts) == 2) { | |
list($prefix, $rest) = $parts; | |
} else { | |
$prefix = null; | |
} | |
if ($prefix != 'openid') { | |
$obj->args->set(array(Auth_OpenID_BARE_NS, $key), $value); | |
} else { | |
$openid_args[$rest] = $value; | |
} | |
} | |
if ($obj->_fromOpenIDArgs($openid_args)) { | |
return $obj; | |
} else { | |
return null; | |
} | |
} | |
static function fromOpenIDArgs($openid_args) | |
{ | |
// Takes an array. | |
// Construct a Message from a parsed KVForm message | |
$obj = new Auth_OpenID_Message(); | |
if ($obj->_fromOpenIDArgs($openid_args)) { | |
return $obj; | |
} else { | |
return null; | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _fromOpenIDArgs($openid_args) | |
{ | |
global $Auth_OpenID_registered_aliases; | |
// Takes an Auth_OpenID_Mapping instance OR an array. | |
if (!Auth_OpenID_Mapping::isA($openid_args)) { | |
$openid_args = new Auth_OpenID_Mapping($openid_args); | |
} | |
$ns_args = array(); | |
// Resolve namespaces | |
foreach ($openid_args->items() as $pair) { | |
list($rest, $value) = $pair; | |
$parts = explode('.', $rest, 2); | |
if (count($parts) == 2) { | |
list($ns_alias, $ns_key) = $parts; | |
} else { | |
$ns_alias = Auth_OpenID_NULL_NAMESPACE; | |
$ns_key = $rest; | |
} | |
if ($ns_alias == 'ns') { | |
if ($this->namespaces->addAlias($value, $ns_key) === null) { | |
return false; | |
} | |
} else if (($ns_alias == Auth_OpenID_NULL_NAMESPACE) && | |
($ns_key == 'ns')) { | |
// null namespace | |
if ($this->setOpenIDNamespace($value, false) === false) { | |
return false; | |
} | |
} else { | |
$ns_args[] = array($ns_alias, $ns_key, $value); | |
} | |
} | |
if (!$this->getOpenIDNamespace()) { | |
if ($this->setOpenIDNamespace(Auth_OpenID_OPENID1_NS, true) === | |
false) { | |
return false; | |
} | |
} | |
// Actually put the pairs into the appropriate namespaces | |
foreach ($ns_args as $triple) { | |
list($ns_alias, $ns_key, $value) = $triple; | |
$ns_uri = $this->namespaces->getNamespaceURI($ns_alias); | |
if ($ns_uri === null) { | |
$ns_uri = $this->_getDefaultNamespace($ns_alias); | |
if ($ns_uri === null) { | |
$ns_uri = Auth_OpenID_OPENID_NS; | |
$ns_key = sprintf('%s.%s', $ns_alias, $ns_key); | |
} else { | |
$this->namespaces->addAlias($ns_uri, $ns_alias, true); | |
} | |
} | |
$this->setArg($ns_uri, $ns_key, $value); | |
} | |
return true; | |
} | |
function _getDefaultNamespace($mystery_alias) | |
{ | |
global $Auth_OpenID_registered_aliases; | |
if ($this->isOpenID1()) { | |
return @$Auth_OpenID_registered_aliases[$mystery_alias]; | |
} | |
return null; | |
} | |
function setOpenIDNamespace($openid_ns_uri, $implicit) | |
{ | |
if (!in_array($openid_ns_uri, $this->allowed_openid_namespaces)) { | |
Auth_OpenID::log('Invalid null namespace: "%s"', $openid_ns_uri); | |
return false; | |
} | |
$succeeded = $this->namespaces->addAlias($openid_ns_uri, | |
Auth_OpenID_NULL_NAMESPACE, | |
$implicit); | |
if ($succeeded === false) { | |
return false; | |
} | |
$this->_openid_ns_uri = $openid_ns_uri; | |
return true; | |
} | |
function getOpenIDNamespace() | |
{ | |
return $this->_openid_ns_uri; | |
} | |
static function fromKVForm($kvform_string) | |
{ | |
// Create a Message from a KVForm string | |
return Auth_OpenID_Message::fromOpenIDArgs( | |
Auth_OpenID_KVForm::toArray($kvform_string)); | |
} | |
function copy() | |
{ | |
return $this; | |
} | |
function toPostArgs() | |
{ | |
// Return all arguments with openid. in front of namespaced | |
// arguments. | |
$args = array(); | |
// Add namespace definitions to the output | |
foreach ($this->namespaces->iteritems() as $pair) { | |
list($ns_uri, $alias) = $pair; | |
if ($this->namespaces->isImplicit($ns_uri)) { | |
continue; | |
} | |
if ($alias == Auth_OpenID_NULL_NAMESPACE) { | |
$ns_key = 'openid.ns'; | |
} else { | |
$ns_key = 'openid.ns.' . $alias; | |
} | |
$args[$ns_key] = $ns_uri; | |
} | |
foreach ($this->args->items() as $pair) { | |
list($ns_parts, $value) = $pair; | |
list($ns_uri, $ns_key) = $ns_parts; | |
$key = $this->getKey($ns_uri, $ns_key); | |
$args[$key] = $value; | |
} | |
return $args; | |
} | |
function toArgs() | |
{ | |
// Return all namespaced arguments, failing if any | |
// non-namespaced arguments exist. | |
$post_args = $this->toPostArgs(); | |
$kvargs = array(); | |
foreach ($post_args as $k => $v) { | |
if (strpos($k, 'openid.') !== 0) { | |
// raise ValueError( | |
// 'This message can only be encoded as a POST, because it ' | |
// 'contains arguments that are not prefixed with "openid."') | |
return null; | |
} else { | |
$kvargs[substr($k, 7)] = $v; | |
} | |
} | |
return $kvargs; | |
} | |
function toFormMarkup($action_url, $form_tag_attrs = null, | |
$submit_text = "Continue") | |
{ | |
$form = "<form accept-charset=\"UTF-8\" ". | |
"enctype=\"application/x-www-form-urlencoded\""; | |
if (!$form_tag_attrs) { | |
$form_tag_attrs = array(); | |
} | |
$form_tag_attrs['action'] = $action_url; | |
$form_tag_attrs['method'] = 'post'; | |
unset($form_tag_attrs['enctype']); | |
unset($form_tag_attrs['accept-charset']); | |
if ($form_tag_attrs) { | |
foreach ($form_tag_attrs as $name => $attr) { | |
$form .= sprintf(" %s=\"%s\"", $name, $attr); | |
} | |
} | |
$form .= ">\n"; | |
foreach ($this->toPostArgs() as $name => $value) { | |
$form .= sprintf( | |
"<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n", | |
$name, urldecode($value)); | |
} | |
$form .= sprintf("<input type=\"submit\" value=\"%s\" />\n", | |
$submit_text); | |
$form .= "</form>\n"; | |
return $form; | |
} | |
function toURL($base_url) | |
{ | |
// Generate a GET URL with the parameters in this message | |
// attached as query parameters. | |
return Auth_OpenID::appendArgs($base_url, $this->toPostArgs()); | |
} | |
function toKVForm() | |
{ | |
// Generate a KVForm string that contains the parameters in | |
// this message. This will fail if the message contains | |
// arguments outside of the 'openid.' prefix. | |
return Auth_OpenID_KVForm::fromArray($this->toArgs()); | |
} | |
function toURLEncoded() | |
{ | |
// Generate an x-www-urlencoded string | |
$args = array(); | |
foreach ($this->toPostArgs() as $k => $v) { | |
$args[] = array($k, $v); | |
} | |
sort($args); | |
return Auth_OpenID::httpBuildQuery($args); | |
} | |
/** | |
* @access private | |
*/ | |
function _fixNS($namespace) | |
{ | |
// Convert an input value into the internally used values of | |
// this object | |
if ($namespace == Auth_OpenID_OPENID_NS) { | |
if ($this->_openid_ns_uri === null) { | |
return new Auth_OpenID_FailureResponse(null, | |
'OpenID namespace not set'); | |
} else { | |
$namespace = $this->_openid_ns_uri; | |
} | |
} | |
if (($namespace != Auth_OpenID_BARE_NS) && | |
(!is_string($namespace))) { | |
//TypeError | |
$err_msg = sprintf("Namespace must be Auth_OpenID_BARE_NS, ". | |
"Auth_OpenID_OPENID_NS or a string. got %s", | |
print_r($namespace, true)); | |
return new Auth_OpenID_FailureResponse(null, $err_msg); | |
} | |
if (($namespace != Auth_OpenID_BARE_NS) && | |
(strpos($namespace, ':') === false)) { | |
// fmt = 'OpenID 2.0 namespace identifiers SHOULD be URIs. Got %r' | |
// warnings.warn(fmt % (namespace,), DeprecationWarning) | |
if ($namespace == 'sreg') { | |
// fmt = 'Using %r instead of "sreg" as namespace' | |
// warnings.warn(fmt % (SREG_URI,), DeprecationWarning,) | |
return Auth_OpenID_SREG_URI; | |
} | |
} | |
return $namespace; | |
} | |
function hasKey($namespace, $ns_key) | |
{ | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
// XXX log me | |
return false; | |
} else { | |
return $this->args->contains(array($namespace, $ns_key)); | |
} | |
} | |
function getKey($namespace, $ns_key) | |
{ | |
// Get the key for a particular namespaced argument | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
return $namespace; | |
} | |
if ($namespace == Auth_OpenID_BARE_NS) { | |
return $ns_key; | |
} | |
$ns_alias = $this->namespaces->getAlias($namespace); | |
// No alias is defined, so no key can exist | |
if ($ns_alias === null) { | |
return null; | |
} | |
if ($ns_alias == Auth_OpenID_NULL_NAMESPACE) { | |
$tail = $ns_key; | |
} else { | |
$tail = sprintf('%s.%s', $ns_alias, $ns_key); | |
} | |
return 'openid.' . $tail; | |
} | |
function getArg($namespace, $key, $default = null) | |
{ | |
// Get a value for a namespaced key. | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
return $namespace; | |
} else { | |
if ((!$this->args->contains(array($namespace, $key))) && | |
($default == Auth_OpenID_NO_DEFAULT)) { | |
$err_msg = sprintf("Namespace %s missing required field %s", | |
$namespace, $key); | |
return new Auth_OpenID_FailureResponse(null, $err_msg); | |
} else { | |
return $this->args->get(array($namespace, $key), $default); | |
} | |
} | |
} | |
function getArgs($namespace) | |
{ | |
// Get the arguments that are defined for this namespace URI | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
return $namespace; | |
} else { | |
$stuff = array(); | |
foreach ($this->args->items() as $pair) { | |
list($key, $value) = $pair; | |
list($pair_ns, $ns_key) = $key; | |
if ($pair_ns == $namespace) { | |
$stuff[$ns_key] = $value; | |
} | |
} | |
return $stuff; | |
} | |
} | |
function updateArgs($namespace, $updates) | |
{ | |
// Set multiple key/value pairs in one call | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
return $namespace; | |
} else { | |
foreach ($updates as $k => $v) { | |
$this->setArg($namespace, $k, $v); | |
} | |
return true; | |
} | |
} | |
function setArg($namespace, $key, $value) | |
{ | |
// Set a single argument in this namespace | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
return $namespace; | |
} else { | |
$this->args->set(array($namespace, $key), $value); | |
if ($namespace !== Auth_OpenID_BARE_NS) { | |
$this->namespaces->add($namespace); | |
} | |
return true; | |
} | |
} | |
function delArg($namespace, $key) | |
{ | |
$namespace = $this->_fixNS($namespace); | |
if (Auth_OpenID::isFailure($namespace)) { | |
return $namespace; | |
} else { | |
return $this->args->del(array($namespace, $key)); | |
} | |
} | |
function getAliasedArg($aliased_key, $default = null) | |
{ | |
if ($aliased_key == 'ns') { | |
// Return the namespace URI for the OpenID namespace | |
return $this->getOpenIDNamespace(); | |
} | |
$parts = explode('.', $aliased_key, 2); | |
if (count($parts) != 2) { | |
$ns = null; | |
} else { | |
list($alias, $key) = $parts; | |
if ($alias == 'ns') { | |
// Return the namespace URI for a namespace alias | |
// parameter. | |
return $this->namespaces->getNamespaceURI($key); | |
} else { | |
$ns = $this->namespaces->getNamespaceURI($alias); | |
} | |
} | |
if ($ns === null) { | |
$key = $aliased_key; | |
$ns = $this->getOpenIDNamespace(); | |
} | |
return $this->getArg($ns, $key, $default); | |
} | |
} | |
<?php | |
/** | |
* A MySQL store. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Require the base class file. | |
*/ | |
require_once "Auth/OpenID/SQLStore.php"; | |
/** | |
* An SQL store that uses MySQL as its backend. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_MySQLStore extends Auth_OpenID_SQLStore { | |
/** | |
* @access private | |
*/ | |
function setSQL() | |
{ | |
$this->sql['nonce_table'] = | |
"CREATE TABLE %s (\n". | |
" server_url VARCHAR(2047) NOT NULL,\n". | |
" timestamp INTEGER NOT NULL,\n". | |
" salt CHAR(40) NOT NULL,\n". | |
" UNIQUE (server_url(255), timestamp, salt)\n". | |
") ENGINE=InnoDB"; | |
$this->sql['assoc_table'] = | |
"CREATE TABLE %s (\n". | |
" server_url BLOB NOT NULL,\n". | |
" handle VARCHAR(255) NOT NULL,\n". | |
" secret BLOB NOT NULL,\n". | |
" issued INTEGER NOT NULL,\n". | |
" lifetime INTEGER NOT NULL,\n". | |
" assoc_type VARCHAR(64) NOT NULL,\n". | |
" PRIMARY KEY (server_url(255), handle)\n". | |
") ENGINE=InnoDB"; | |
$this->sql['set_assoc'] = | |
"REPLACE INTO %s (server_url, handle, secret, issued,\n". | |
" lifetime, assoc_type) VALUES (?, ?, !, ?, ?, ?)"; | |
$this->sql['get_assocs'] = | |
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". | |
"WHERE server_url = ?"; | |
$this->sql['get_assoc'] = | |
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". | |
"WHERE server_url = ? AND handle = ?"; | |
$this->sql['remove_assoc'] = | |
"DELETE FROM %s WHERE server_url = ? AND handle = ?"; | |
$this->sql['add_nonce'] = | |
"INSERT INTO %s (server_url, timestamp, salt) VALUES (?, ?, ?)"; | |
$this->sql['clean_nonce'] = | |
"DELETE FROM %s WHERE timestamp < ?"; | |
$this->sql['clean_assoc'] = | |
"DELETE FROM %s WHERE issued + lifetime < ?"; | |
} | |
/** | |
* @access private | |
*/ | |
function blobEncode($blob) | |
{ | |
return "0x" . bin2hex($blob); | |
} | |
} | |
<?php | |
/** | |
* Nonce-related functionality. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Need CryptUtil to generate random strings. | |
*/ | |
require_once 'Auth/OpenID/CryptUtil.php'; | |
/** | |
* This is the characters that the nonces are made from. | |
*/ | |
define('Auth_OpenID_Nonce_CHRS',"abcdefghijklmnopqrstuvwxyz" . | |
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); | |
// Keep nonces for five hours (allow five hours for the combination of | |
// request time and clock skew). This is probably way more than is | |
// necessary, but there is not much overhead in storing nonces. | |
global $Auth_OpenID_SKEW; | |
$Auth_OpenID_SKEW = 60 * 60 * 5; | |
define('Auth_OpenID_Nonce_REGEX', | |
'/(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z(.*)/'); | |
define('Auth_OpenID_Nonce_TIME_FMT', | |
'%Y-%m-%dT%H:%M:%SZ'); | |
function Auth_OpenID_splitNonce($nonce_string) | |
{ | |
// Extract a timestamp from the given nonce string | |
$result = preg_match(Auth_OpenID_Nonce_REGEX, $nonce_string, $matches); | |
if ($result != 1 || count($matches) != 8) { | |
return null; | |
} | |
list($unused, | |
$tm_year, | |
$tm_mon, | |
$tm_mday, | |
$tm_hour, | |
$tm_min, | |
$tm_sec, | |
$uniquifier) = $matches; | |
$timestamp = | |
@gmmktime($tm_hour, $tm_min, $tm_sec, $tm_mon, $tm_mday, $tm_year); | |
if ($timestamp === false || $timestamp < 0) { | |
return null; | |
} | |
return array($timestamp, $uniquifier); | |
} | |
function Auth_OpenID_checkTimestamp($nonce_string, | |
$allowed_skew = null, | |
$now = null) | |
{ | |
// Is the timestamp that is part of the specified nonce string | |
// within the allowed clock-skew of the current time? | |
global $Auth_OpenID_SKEW; | |
if ($allowed_skew === null) { | |
$allowed_skew = $Auth_OpenID_SKEW; | |
} | |
$parts = Auth_OpenID_splitNonce($nonce_string); | |
if ($parts == null) { | |
return false; | |
} | |
if ($now === null) { | |
$now = time(); | |
} | |
$stamp = $parts[0]; | |
// Time after which we should not use the nonce | |
$past = $now - $allowed_skew; | |
// Time that is too far in the future for us to allow | |
$future = $now + $allowed_skew; | |
// the stamp is not too far in the future and is not too far | |
// in the past | |
return (($past <= $stamp) && ($stamp <= $future)); | |
} | |
function Auth_OpenID_mkNonce($when = null) | |
{ | |
// Generate a nonce with the current timestamp | |
$salt = Auth_OpenID_CryptUtil::randomString( | |
6, Auth_OpenID_Nonce_CHRS); | |
if ($when === null) { | |
// It's safe to call time() with no arguments; it returns a | |
// GMT unix timestamp on PHP 4 and PHP 5. gmmktime() with no | |
// args returns a local unix timestamp on PHP 4, so don't use | |
// that. | |
$when = time(); | |
} | |
$time_str = gmstrftime(Auth_OpenID_Nonce_TIME_FMT, $when); | |
return $time_str . $salt; | |
} | |
<?php | |
/** | |
* An implementation of the OpenID Provider Authentication Policy | |
* Extension 1.0 | |
* | |
* See: | |
* http://openid.net/developers/specs/ | |
*/ | |
require_once "Auth/OpenID/Extension.php"; | |
define('Auth_OpenID_PAPE_NS_URI', | |
"http://specs.openid.net/extensions/pape/1.0"); | |
define('PAPE_AUTH_MULTI_FACTOR_PHYSICAL', | |
'http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical'); | |
define('PAPE_AUTH_MULTI_FACTOR', | |
'http://schemas.openid.net/pape/policies/2007/06/multi-factor'); | |
define('PAPE_AUTH_PHISHING_RESISTANT', | |
'http://schemas.openid.net/pape/policies/2007/06/phishing-resistant'); | |
define('PAPE_TIME_VALIDATOR', | |
'/^[0-9]{4,4}-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]Z$/'); | |
/** | |
* A Provider Authentication Policy request, sent from a relying party | |
* to a provider | |
* | |
* preferred_auth_policies: The authentication policies that | |
* the relying party prefers | |
* | |
* max_auth_age: The maximum time, in seconds, that the relying party | |
* wants to allow to have elapsed before the user must re-authenticate | |
*/ | |
class Auth_OpenID_PAPE_Request extends Auth_OpenID_Extension { | |
var $ns_alias = 'pape'; | |
var $ns_uri = Auth_OpenID_PAPE_NS_URI; | |
function Auth_OpenID_PAPE_Request($preferred_auth_policies=null, | |
$max_auth_age=null) | |
{ | |
if ($preferred_auth_policies === null) { | |
$preferred_auth_policies = array(); | |
} | |
$this->preferred_auth_policies = $preferred_auth_policies; | |
$this->max_auth_age = $max_auth_age; | |
} | |
/** | |
* Add an acceptable authentication policy URI to this request | |
* | |
* This method is intended to be used by the relying party to add | |
* acceptable authentication types to the request. | |
* | |
* policy_uri: The identifier for the preferred type of | |
* authentication. | |
*/ | |
function addPolicyURI($policy_uri) | |
{ | |
if (!in_array($policy_uri, $this->preferred_auth_policies)) { | |
$this->preferred_auth_policies[] = $policy_uri; | |
} | |
} | |
function getExtensionArgs() | |
{ | |
$ns_args = array( | |
'preferred_auth_policies' => | |
implode(' ', $this->preferred_auth_policies) | |
); | |
if ($this->max_auth_age !== null) { | |
$ns_args['max_auth_age'] = strval($this->max_auth_age); | |
} | |
return $ns_args; | |
} | |
/** | |
* Instantiate a Request object from the arguments in a checkid_* | |
* OpenID message | |
*/ | |
static function fromOpenIDRequest($request) | |
{ | |
$obj = new Auth_OpenID_PAPE_Request(); | |
$args = $request->message->getArgs(Auth_OpenID_PAPE_NS_URI); | |
if ($args === null || $args === array()) { | |
return null; | |
} | |
$obj->parseExtensionArgs($args); | |
return $obj; | |
} | |
/** | |
* Set the state of this request to be that expressed in these | |
* PAPE arguments | |
* | |
* @param args: The PAPE arguments without a namespace | |
*/ | |
function parseExtensionArgs($args) | |
{ | |
// preferred_auth_policies is a space-separated list of policy | |
// URIs | |
$this->preferred_auth_policies = array(); | |
$policies_str = Auth_OpenID::arrayGet($args, 'preferred_auth_policies'); | |
if ($policies_str) { | |
foreach (explode(' ', $policies_str) as $uri) { | |
if (!in_array($uri, $this->preferred_auth_policies)) { | |
$this->preferred_auth_policies[] = $uri; | |
} | |
} | |
} | |
// max_auth_age is base-10 integer number of seconds | |
$max_auth_age_str = Auth_OpenID::arrayGet($args, 'max_auth_age'); | |
if ($max_auth_age_str) { | |
$this->max_auth_age = Auth_OpenID::intval($max_auth_age_str); | |
} else { | |
$this->max_auth_age = null; | |
} | |
} | |
/** | |
* Given a list of authentication policy URIs that a provider | |
* supports, this method returns the subsequence of those types | |
* that are preferred by the relying party. | |
* | |
* @param supported_types: A sequence of authentication policy | |
* type URIs that are supported by a provider | |
* | |
* @return array The sub-sequence of the supported types that are | |
* preferred by the relying party. This list will be ordered in | |
* the order that the types appear in the supported_types | |
* sequence, and may be empty if the provider does not prefer any | |
* of the supported authentication types. | |
*/ | |
function preferredTypes($supported_types) | |
{ | |
$result = array(); | |
foreach ($supported_types as $st) { | |
if (in_array($st, $this->preferred_auth_policies)) { | |
$result[] = $st; | |
} | |
} | |
return $result; | |
} | |
} | |
/** | |
* A Provider Authentication Policy response, sent from a provider to | |
* a relying party | |
*/ | |
class Auth_OpenID_PAPE_Response extends Auth_OpenID_Extension { | |
var $ns_alias = 'pape'; | |
var $ns_uri = Auth_OpenID_PAPE_NS_URI; | |
function Auth_OpenID_PAPE_Response($auth_policies=null, $auth_time=null, | |
$nist_auth_level=null) | |
{ | |
if ($auth_policies) { | |
$this->auth_policies = $auth_policies; | |
} else { | |
$this->auth_policies = array(); | |
} | |
$this->auth_time = $auth_time; | |
$this->nist_auth_level = $nist_auth_level; | |
} | |
/** | |
* Add a authentication policy to this response | |
* | |
* This method is intended to be used by the provider to add a | |
* policy that the provider conformed to when authenticating the | |
* user. | |
* | |
* @param policy_uri: The identifier for the preferred type of | |
* authentication. | |
*/ | |
function addPolicyURI($policy_uri) | |
{ | |
if (!in_array($policy_uri, $this->auth_policies)) { | |
$this->auth_policies[] = $policy_uri; | |
} | |
} | |
/** | |
* Create an Auth_OpenID_PAPE_Response object from a successful | |
* OpenID library response. | |
* | |
* @param success_response $success_response A SuccessResponse | |
* from Auth_OpenID_Consumer::complete() | |
* | |
* @returns: A provider authentication policy response from the | |
* data that was supplied with the id_res response. | |
*/ | |
static function fromSuccessResponse($success_response) | |
{ | |
$obj = new Auth_OpenID_PAPE_Response(); | |
// PAPE requires that the args be signed. | |
$args = $success_response->getSignedNS(Auth_OpenID_PAPE_NS_URI); | |
if ($args === null || $args === array()) { | |
return null; | |
} | |
$result = $obj->parseExtensionArgs($args); | |
if ($result === false) { | |
return null; | |
} else { | |
return $obj; | |
} | |
} | |
/** | |
* Parse the provider authentication policy arguments into the | |
* internal state of this object | |
* | |
* @param args: unqualified provider authentication policy | |
* arguments | |
* | |
* @param strict: Whether to return false when bad data is | |
* encountered | |
* | |
* @return null The data is parsed into the internal fields of | |
* this object. | |
*/ | |
function parseExtensionArgs($args, $strict=false) | |
{ | |
$policies_str = Auth_OpenID::arrayGet($args, 'auth_policies'); | |
if ($policies_str && $policies_str != "none") { | |
$this->auth_policies = explode(" ", $policies_str); | |
} | |
$nist_level_str = Auth_OpenID::arrayGet($args, 'nist_auth_level'); | |
if ($nist_level_str !== null) { | |
$nist_level = Auth_OpenID::intval($nist_level_str); | |
if ($nist_level === false) { | |
if ($strict) { | |
return false; | |
} else { | |
$nist_level = null; | |
} | |
} | |
if (0 <= $nist_level && $nist_level < 5) { | |
$this->nist_auth_level = $nist_level; | |
} else if ($strict) { | |
return false; | |
} | |
} | |
$auth_time = Auth_OpenID::arrayGet($args, 'auth_time'); | |
if ($auth_time !== null) { | |
if (preg_match(PAPE_TIME_VALIDATOR, $auth_time)) { | |
$this->auth_time = $auth_time; | |
} else if ($strict) { | |
return false; | |
} | |
} | |
} | |
function getExtensionArgs() | |
{ | |
$ns_args = array(); | |
if (count($this->auth_policies) > 0) { | |
$ns_args['auth_policies'] = implode(' ', $this->auth_policies); | |
} else { | |
$ns_args['auth_policies'] = 'none'; | |
} | |
if ($this->nist_auth_level !== null) { | |
if (!in_array($this->nist_auth_level, range(0, 4), true)) { | |
return false; | |
} | |
$ns_args['nist_auth_level'] = strval($this->nist_auth_level); | |
} | |
if ($this->auth_time !== null) { | |
if (!preg_match(PAPE_TIME_VALIDATOR, $this->auth_time)) { | |
return false; | |
} | |
$ns_args['auth_time'] = $this->auth_time; | |
} | |
return $ns_args; | |
} | |
} | |
<?php | |
/** | |
* This module implements a VERY limited parser that finds <link> tags | |
* in the head of HTML or XHTML documents and parses out their | |
* attributes according to the OpenID spec. It is a liberal parser, | |
* but it requires these things from the data in order to work: | |
* | |
* - There must be an open <html> tag | |
* | |
* - There must be an open <head> tag inside of the <html> tag | |
* | |
* - Only <link>s that are found inside of the <head> tag are parsed | |
* (this is by design) | |
* | |
* - The parser follows the OpenID specification in resolving the | |
* attributes of the link tags. This means that the attributes DO | |
* NOT get resolved as they would by an XML or HTML parser. In | |
* particular, only certain entities get replaced, and href | |
* attributes do not get resolved relative to a base URL. | |
* | |
* From http://openid.net/specs.bml: | |
* | |
* - The openid.server URL MUST be an absolute URL. OpenID consumers | |
* MUST NOT attempt to resolve relative URLs. | |
* | |
* - The openid.server URL MUST NOT include entities other than &, | |
* <, >, and ". | |
* | |
* The parser ignores SGML comments and <![CDATA[blocks]]>. Both kinds | |
* of quoting are allowed for attributes. | |
* | |
* The parser deals with invalid markup in these ways: | |
* | |
* - Tag names are not case-sensitive | |
* | |
* - The <html> tag is accepted even when it is not at the top level | |
* | |
* - The <head> tag is accepted even when it is not a direct child of | |
* the <html> tag, but a <html> tag must be an ancestor of the | |
* <head> tag | |
* | |
* - <link> tags are accepted even when they are not direct children | |
* of the <head> tag, but a <head> tag must be an ancestor of the | |
* <link> tag | |
* | |
* - If there is no closing tag for an open <html> or <head> tag, the | |
* remainder of the document is viewed as being inside of the | |
* tag. If there is no closing tag for a <link> tag, the link tag is | |
* treated as a short tag. Exceptions to this rule are that <html> | |
* closes <html> and <body> or <head> closes <head> | |
* | |
* - Attributes of the <link> tag are not required to be quoted. | |
* | |
* - In the case of duplicated attribute names, the attribute coming | |
* last in the tag will be the value returned. | |
* | |
* - Any text that does not parse as an attribute within a link tag | |
* will be ignored. (e.g. <link pumpkin rel='openid.server' /> will | |
* ignore pumpkin) | |
* | |
* - If there are more than one <html> or <head> tag, the parser only | |
* looks inside of the first one. | |
* | |
* - The contents of <script> tags are ignored entirely, except | |
* unclosed <script> tags. Unclosed <script> tags are ignored. | |
* | |
* - Any other invalid markup is ignored, including unclosed SGML | |
* comments and unclosed <![CDATA[blocks. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @access private | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Require Auth_OpenID::arrayGet(). | |
*/ | |
require_once "Auth/OpenID.php"; | |
class Auth_OpenID_Parse { | |
/** | |
* Specify some flags for use with regex matching. | |
*/ | |
var $_re_flags = "si"; | |
/** | |
* Stuff to remove before we start looking for tags | |
*/ | |
var $_removed_re = | |
"<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b(?!:)[^>]*>.*?<\/script>"; | |
/** | |
* Starts with the tag name at a word boundary, where the tag name | |
* is not a namespace | |
*/ | |
var $_tag_expr = "<%s\b(?!:)([^>]*?)(?:\/>|>(.*)(?:<\/?%s\s*>|\Z))"; | |
var $_attr_find = '\b(\w+)=("[^"]*"|\'[^\']*\'|[^\'"\s\/<>]+)'; | |
var $_open_tag_expr = "<%s\b"; | |
var $_close_tag_expr = "<((\/%s\b)|(%s[^>\/]*\/))>"; | |
function Auth_OpenID_Parse() | |
{ | |
$this->_link_find = sprintf("/<link\b(?!:)([^>]*)(?!<)>/%s", | |
$this->_re_flags); | |
$this->_entity_replacements = array( | |
'amp' => '&', | |
'lt' => '<', | |
'gt' => '>', | |
'quot' => '"' | |
); | |
$this->_attr_find = sprintf("/%s/%s", | |
$this->_attr_find, | |
$this->_re_flags); | |
$this->_removed_re = sprintf("/%s/%s", | |
$this->_removed_re, | |
$this->_re_flags); | |
$this->_ent_replace = | |
sprintf("&(%s);", implode("|", | |
$this->_entity_replacements)); | |
} | |
/** | |
* Returns a regular expression that will match a given tag in an | |
* SGML string. | |
*/ | |
function tagMatcher($tag_name, $close_tags = null) | |
{ | |
$expr = $this->_tag_expr; | |
if ($close_tags) { | |
$options = implode("|", array_merge(array($tag_name), $close_tags)); | |
$closer = sprintf("(?:%s)", $options); | |
} else { | |
$closer = $tag_name; | |
} | |
$expr = sprintf($expr, $tag_name, $closer); | |
return sprintf("/%s/%s", $expr, $this->_re_flags); | |
} | |
function openTag($tag_name) | |
{ | |
$expr = sprintf($this->_open_tag_expr, $tag_name); | |
return sprintf("/%s/%s", $expr, $this->_re_flags); | |
} | |
function closeTag($tag_name) | |
{ | |
$expr = sprintf($this->_close_tag_expr, $tag_name, $tag_name); | |
return sprintf("/%s/%s", $expr, $this->_re_flags); | |
} | |
function htmlBegin($s) | |
{ | |
$matches = array(); | |
$result = preg_match($this->openTag('html'), $s, | |
$matches, PREG_OFFSET_CAPTURE); | |
if ($result === false || !$matches) { | |
return false; | |
} | |
// Return the offset of the first match. | |
return $matches[0][1]; | |
} | |
function htmlEnd($s) | |
{ | |
$matches = array(); | |
$result = preg_match($this->closeTag('html'), $s, | |
$matches, PREG_OFFSET_CAPTURE); | |
if ($result === false || !$matches) { | |
return false; | |
} | |
// Return the offset of the first match. | |
return $matches[count($matches) - 1][1]; | |
} | |
function headFind() | |
{ | |
return $this->tagMatcher('head', array('body', 'html')); | |
} | |
function replaceEntities($str) | |
{ | |
foreach ($this->_entity_replacements as $old => $new) { | |
$str = preg_replace(sprintf("/&%s;/", $old), $new, $str); | |
} | |
return $str; | |
} | |
function removeQuotes($str) | |
{ | |
$matches = array(); | |
$double = '/^"(.*)"$/'; | |
$single = "/^\'(.*)\'$/"; | |
if (preg_match($double, $str, $matches)) { | |
return $matches[1]; | |
} else if (preg_match($single, $str, $matches)) { | |
return $matches[1]; | |
} else { | |
return $str; | |
} | |
} | |
function match($regexp, $text, &$match) | |
{ | |
if (!is_callable('mb_ereg_search_init')) { | |
return preg_match($regexp, $text, $match); | |
} | |
$regexp = substr($regexp, 1, strlen($regexp) - 2 - strlen($this->_re_flags)); | |
mb_ereg_search_init($text); | |
if (!mb_ereg_search($regexp)) { | |
return false; | |
} | |
$match = mb_ereg_search_getregs(); | |
return true; | |
} | |
/** | |
* Find all link tags in a string representing a HTML document and | |
* return a list of their attributes. | |
* | |
* @todo This is quite ineffective and may fail with the default | |
* pcre.backtrack_limit of 100000 in PHP 5.2, if $html is big. | |
* It should rather use stripos (in PHP5) or strpos()+strtoupper() | |
* in PHP4 to manage this. | |
* | |
* @param string $html The text to parse | |
* @return array $list An array of arrays of attributes, one for each | |
* link tag | |
*/ | |
function parseLinkAttrs($html) | |
{ | |
$stripped = preg_replace($this->_removed_re, | |
"", | |
$html); | |
$html_begin = $this->htmlBegin($stripped); | |
$html_end = $this->htmlEnd($stripped); | |
if ($html_begin === false) { | |
return array(); | |
} | |
if ($html_end === false) { | |
$html_end = strlen($stripped); | |
} | |
$stripped = substr($stripped, $html_begin, | |
$html_end - $html_begin); | |
// Workaround to prevent PREG_BACKTRACK_LIMIT_ERROR: | |
$old_btlimit = ini_set( 'pcre.backtrack_limit', -1 ); | |
// Try to find the <HEAD> tag. | |
$head_re = $this->headFind(); | |
$head_match = array(); | |
if (!$this->match($head_re, $stripped, $head_match)) { | |
ini_set( 'pcre.backtrack_limit', $old_btlimit ); | |
return array(); | |
} | |
$link_data = array(); | |
$link_matches = array(); | |
if (!preg_match_all($this->_link_find, $head_match[0], | |
$link_matches)) { | |
ini_set( 'pcre.backtrack_limit', $old_btlimit ); | |
return array(); | |
} | |
foreach ($link_matches[0] as $link) { | |
$attr_matches = array(); | |
preg_match_all($this->_attr_find, $link, $attr_matches); | |
$link_attrs = array(); | |
foreach ($attr_matches[0] as $index => $full_match) { | |
$name = $attr_matches[1][$index]; | |
$value = $this->replaceEntities( | |
$this->removeQuotes($attr_matches[2][$index])); | |
$link_attrs[strtolower($name)] = $value; | |
} | |
$link_data[] = $link_attrs; | |
} | |
ini_set( 'pcre.backtrack_limit', $old_btlimit ); | |
return $link_data; | |
} | |
function relMatches($rel_attr, $target_rel) | |
{ | |
// Does this target_rel appear in the rel_str? | |
// XXX: TESTME | |
$rels = preg_split("/\s+/", trim($rel_attr)); | |
foreach ($rels as $rel) { | |
$rel = strtolower($rel); | |
if ($rel == $target_rel) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
function linkHasRel($link_attrs, $target_rel) | |
{ | |
// Does this link have target_rel as a relationship? | |
// XXX: TESTME | |
$rel_attr = Auth_OpeniD::arrayGet($link_attrs, 'rel', null); | |
return ($rel_attr && $this->relMatches($rel_attr, | |
$target_rel)); | |
} | |
function findLinksRel($link_attrs_list, $target_rel) | |
{ | |
// Filter the list of link attributes on whether it has | |
// target_rel as a relationship. | |
// XXX: TESTME | |
$result = array(); | |
foreach ($link_attrs_list as $attr) { | |
if ($this->linkHasRel($attr, $target_rel)) { | |
$result[] = $attr; | |
} | |
} | |
return $result; | |
} | |
function findFirstHref($link_attrs_list, $target_rel) | |
{ | |
// Return the value of the href attribute for the first link | |
// tag in the list that has target_rel as a relationship. | |
// XXX: TESTME | |
$matches = $this->findLinksRel($link_attrs_list, | |
$target_rel); | |
if (!$matches) { | |
return null; | |
} | |
$first = $matches[0]; | |
return Auth_OpenID::arrayGet($first, 'href', null); | |
} | |
} | |
function Auth_OpenID_legacy_discover($html_text, $server_rel, | |
$delegate_rel) | |
{ | |
$p = new Auth_OpenID_Parse(); | |
$link_attrs = $p->parseLinkAttrs($html_text); | |
$server_url = $p->findFirstHref($link_attrs, | |
$server_rel); | |
if ($server_url === null) { | |
return false; | |
} else { | |
$delegate_url = $p->findFirstHref($link_attrs, | |
$delegate_rel); | |
return array($delegate_url, $server_url); | |
} | |
} | |
<?php | |
/** | |
* A PostgreSQL store. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Require the base class file. | |
*/ | |
require_once "Auth/OpenID/SQLStore.php"; | |
/** | |
* An SQL store that uses PostgreSQL as its backend. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_PostgreSQLStore extends Auth_OpenID_SQLStore { | |
/** | |
* @access private | |
*/ | |
function setSQL() | |
{ | |
$this->sql['nonce_table'] = | |
"CREATE TABLE %s (server_url VARCHAR(2047) NOT NULL, ". | |
"timestamp INTEGER NOT NULL, ". | |
"salt CHAR(40) NOT NULL, ". | |
"UNIQUE (server_url, timestamp, salt))"; | |
$this->sql['assoc_table'] = | |
"CREATE TABLE %s (server_url VARCHAR(2047) NOT NULL, ". | |
"handle VARCHAR(255) NOT NULL, ". | |
"secret BYTEA NOT NULL, ". | |
"issued INTEGER NOT NULL, ". | |
"lifetime INTEGER NOT NULL, ". | |
"assoc_type VARCHAR(64) NOT NULL, ". | |
"PRIMARY KEY (server_url, handle), ". | |
"CONSTRAINT secret_length_constraint CHECK ". | |
"(LENGTH(secret) <= 128))"; | |
$this->sql['set_assoc'] = | |
array( | |
'insert_assoc' => "INSERT INTO %s (server_url, handle, ". | |
"secret, issued, lifetime, assoc_type) VALUES ". | |
"(?, ?, '!', ?, ?, ?)", | |
'update_assoc' => "UPDATE %s SET secret = '!', issued = ?, ". | |
"lifetime = ?, assoc_type = ? WHERE server_url = ? AND ". | |
"handle = ?" | |
); | |
$this->sql['get_assocs'] = | |
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". | |
"WHERE server_url = ?"; | |
$this->sql['get_assoc'] = | |
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". | |
"WHERE server_url = ? AND handle = ?"; | |
$this->sql['remove_assoc'] = | |
"DELETE FROM %s WHERE server_url = ? AND handle = ?"; | |
$this->sql['add_nonce'] = | |
"INSERT INTO %s (server_url, timestamp, salt) VALUES ". | |
"(?, ?, ?)" | |
; | |
$this->sql['clean_nonce'] = | |
"DELETE FROM %s WHERE timestamp < ?"; | |
$this->sql['clean_assoc'] = | |
"DELETE FROM %s WHERE issued + lifetime < ?"; | |
} | |
/** | |
* @access private | |
*/ | |
function _set_assoc($server_url, $handle, $secret, $issued, $lifetime, | |
$assoc_type) | |
{ | |
$result = $this->_get_assoc($server_url, $handle); | |
if ($result) { | |
// Update the table since this associations already exists. | |
$this->connection->query($this->sql['set_assoc']['update_assoc'], | |
array($secret, $issued, $lifetime, | |
$assoc_type, $server_url, $handle)); | |
} else { | |
// Insert a new record because this association wasn't | |
// found. | |
$this->connection->query($this->sql['set_assoc']['insert_assoc'], | |
array($server_url, $handle, $secret, | |
$issued, $lifetime, $assoc_type)); | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function blobEncode($blob) | |
{ | |
return $this->_octify($blob); | |
} | |
/** | |
* @access private | |
*/ | |
function blobDecode($blob) | |
{ | |
return $this->_unoctify($blob); | |
} | |
} | |
<?php | |
/** | |
* SQL-backed OpenID stores. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/Interface.php'; | |
require_once 'Auth/OpenID/Nonce.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID.php'; | |
/** | |
* @access private | |
*/ | |
require_once 'Auth/OpenID/Nonce.php'; | |
/** | |
* This is the parent class for the SQL stores, which contains the | |
* logic common to all of the SQL stores. | |
* | |
* The table names used are determined by the class variables | |
* associations_table_name and nonces_table_name. To change the name | |
* of the tables used, pass new table names into the constructor. | |
* | |
* To create the tables with the proper schema, see the createTables | |
* method. | |
* | |
* This class shouldn't be used directly. Use one of its subclasses | |
* instead, as those contain the code necessary to use a specific | |
* database. If you're an OpenID integrator and you'd like to create | |
* an SQL-driven store that wraps an application's database | |
* abstraction, be sure to create a subclass of | |
* {@link Auth_OpenID_DatabaseConnection} that calls the application's | |
* database abstraction calls. Then, pass an instance of your new | |
* database connection class to your SQLStore subclass constructor. | |
* | |
* All methods other than the constructor and createTables should be | |
* considered implementation details. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_SQLStore extends Auth_OpenID_OpenIDStore { | |
/** | |
* This creates a new SQLStore instance. It requires an | |
* established database connection be given to it, and it allows | |
* overriding the default table names. | |
* | |
* @param connection $connection This must be an established | |
* connection to a database of the correct type for the SQLStore | |
* subclass you're using. This must either be an PEAR DB | |
* connection handle or an instance of a subclass of | |
* Auth_OpenID_DatabaseConnection. | |
* | |
* @param associations_table: This is an optional parameter to | |
* specify the name of the table used for storing associations. | |
* The default value is 'oid_associations'. | |
* | |
* @param nonces_table: This is an optional parameter to specify | |
* the name of the table used for storing nonces. The default | |
* value is 'oid_nonces'. | |
*/ | |
function Auth_OpenID_SQLStore($connection, | |
$associations_table = null, | |
$nonces_table = null) | |
{ | |
$this->associations_table_name = "oid_associations"; | |
$this->nonces_table_name = "oid_nonces"; | |
// Check the connection object type to be sure it's a PEAR | |
// database connection. | |
if (!(is_object($connection) && | |
(is_subclass_of($connection, 'db_common') || | |
is_subclass_of($connection, | |
'auth_openid_databaseconnection')))) { | |
trigger_error("Auth_OpenID_SQLStore expected PEAR connection " . | |
"object (got ".get_class($connection).")", | |
E_USER_ERROR); | |
return; | |
} | |
$this->connection = $connection; | |
// Be sure to set the fetch mode so the results are keyed on | |
// column name instead of column index. This is a PEAR | |
// constant, so only try to use it if PEAR is present. Note | |
// that Auth_Openid_Databaseconnection instances need not | |
// implement ::setFetchMode for this reason. | |
if (is_subclass_of($this->connection, 'db_common')) { | |
$this->connection->setFetchMode(DB_FETCHMODE_ASSOC); | |
} | |
if ($associations_table) { | |
$this->associations_table_name = $associations_table; | |
} | |
if ($nonces_table) { | |
$this->nonces_table_name = $nonces_table; | |
} | |
$this->max_nonce_age = 6 * 60 * 60; | |
// Be sure to run the database queries with auto-commit mode | |
// turned OFF, because we want every function to run in a | |
// transaction, implicitly. As a rule, methods named with a | |
// leading underscore will NOT control transaction behavior. | |
// Callers of these methods will worry about transactions. | |
$this->connection->autoCommit(false); | |
// Create an empty SQL strings array. | |
$this->sql = array(); | |
// Call this method (which should be overridden by subclasses) | |
// to populate the $this->sql array with SQL strings. | |
$this->setSQL(); | |
// Verify that all required SQL statements have been set, and | |
// raise an error if any expected SQL strings were either | |
// absent or empty. | |
list($missing, $empty) = $this->_verifySQL(); | |
if ($missing) { | |
trigger_error("Expected keys in SQL query list: " . | |
implode(", ", $missing), | |
E_USER_ERROR); | |
return; | |
} | |
if ($empty) { | |
trigger_error("SQL list keys have no SQL strings: " . | |
implode(", ", $empty), | |
E_USER_ERROR); | |
return; | |
} | |
// Add table names to queries. | |
$this->_fixSQL(); | |
} | |
function tableExists($table_name) | |
{ | |
return !$this->isError( | |
$this->connection->query( | |
sprintf("SELECT * FROM %s LIMIT 0", | |
$table_name))); | |
} | |
/** | |
* Returns true if $value constitutes a database error; returns | |
* false otherwise. | |
*/ | |
function isError($value) | |
{ | |
return PEAR::isError($value); | |
} | |
/** | |
* Converts a query result to a boolean. If the result is a | |
* database error according to $this->isError(), this returns | |
* false; otherwise, this returns true. | |
*/ | |
function resultToBool($obj) | |
{ | |
if ($this->isError($obj)) { | |
return false; | |
} else { | |
return true; | |
} | |
} | |
/** | |
* This method should be overridden by subclasses. This method is | |
* called by the constructor to set values in $this->sql, which is | |
* an array keyed on sql name. | |
*/ | |
function setSQL() | |
{ | |
} | |
/** | |
* Resets the store by removing all records from the store's | |
* tables. | |
*/ | |
function reset() | |
{ | |
$this->connection->query(sprintf("DELETE FROM %s", | |
$this->associations_table_name)); | |
$this->connection->query(sprintf("DELETE FROM %s", | |
$this->nonces_table_name)); | |
} | |
/** | |
* @access private | |
*/ | |
function _verifySQL() | |
{ | |
$missing = array(); | |
$empty = array(); | |
$required_sql_keys = array( | |
'nonce_table', | |
'assoc_table', | |
'set_assoc', | |
'get_assoc', | |
'get_assocs', | |
'remove_assoc' | |
); | |
foreach ($required_sql_keys as $key) { | |
if (!array_key_exists($key, $this->sql)) { | |
$missing[] = $key; | |
} else if (!$this->sql[$key]) { | |
$empty[] = $key; | |
} | |
} | |
return array($missing, $empty); | |
} | |
/** | |
* @access private | |
*/ | |
function _fixSQL() | |
{ | |
$replacements = array( | |
array( | |
'value' => $this->nonces_table_name, | |
'keys' => array('nonce_table', | |
'add_nonce', | |
'clean_nonce') | |
), | |
array( | |
'value' => $this->associations_table_name, | |
'keys' => array('assoc_table', | |
'set_assoc', | |
'get_assoc', | |
'get_assocs', | |
'remove_assoc', | |
'clean_assoc') | |
) | |
); | |
foreach ($replacements as $item) { | |
$value = $item['value']; | |
$keys = $item['keys']; | |
foreach ($keys as $k) { | |
if (is_array($this->sql[$k])) { | |
foreach ($this->sql[$k] as $part_key => $part_value) { | |
$this->sql[$k][$part_key] = sprintf($part_value, | |
$value); | |
} | |
} else { | |
$this->sql[$k] = sprintf($this->sql[$k], $value); | |
} | |
} | |
} | |
} | |
function blobDecode($blob) | |
{ | |
return $blob; | |
} | |
function blobEncode($str) | |
{ | |
return $str; | |
} | |
function createTables() | |
{ | |
$this->connection->autoCommit(true); | |
$n = $this->create_nonce_table(); | |
$a = $this->create_assoc_table(); | |
$this->connection->autoCommit(false); | |
if ($n && $a) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
function create_nonce_table() | |
{ | |
if (!$this->tableExists($this->nonces_table_name)) { | |
$r = $this->connection->query($this->sql['nonce_table']); | |
return $this->resultToBool($r); | |
} | |
return true; | |
} | |
function create_assoc_table() | |
{ | |
if (!$this->tableExists($this->associations_table_name)) { | |
$r = $this->connection->query($this->sql['assoc_table']); | |
return $this->resultToBool($r); | |
} | |
return true; | |
} | |
/** | |
* @access private | |
*/ | |
function _set_assoc($server_url, $handle, $secret, $issued, | |
$lifetime, $assoc_type) | |
{ | |
return $this->connection->query($this->sql['set_assoc'], | |
array( | |
$server_url, | |
$handle, | |
$secret, | |
$issued, | |
$lifetime, | |
$assoc_type)); | |
} | |
function storeAssociation($server_url, $association) | |
{ | |
if ($this->resultToBool($this->_set_assoc( | |
$server_url, | |
$association->handle, | |
$this->blobEncode( | |
$association->secret), | |
$association->issued, | |
$association->lifetime, | |
$association->assoc_type | |
))) { | |
$this->connection->commit(); | |
} else { | |
$this->connection->rollback(); | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _get_assoc($server_url, $handle) | |
{ | |
$result = $this->connection->getRow($this->sql['get_assoc'], | |
array($server_url, $handle)); | |
if ($this->isError($result)) { | |
return null; | |
} else { | |
return $result; | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _get_assocs($server_url) | |
{ | |
$result = $this->connection->getAll($this->sql['get_assocs'], | |
array($server_url)); | |
if ($this->isError($result)) { | |
return array(); | |
} else { | |
return $result; | |
} | |
} | |
function removeAssociation($server_url, $handle) | |
{ | |
if ($this->_get_assoc($server_url, $handle) == null) { | |
return false; | |
} | |
if ($this->resultToBool($this->connection->query( | |
$this->sql['remove_assoc'], | |
array($server_url, $handle)))) { | |
$this->connection->commit(); | |
} else { | |
$this->connection->rollback(); | |
} | |
return true; | |
} | |
function getAssociation($server_url, $handle = null) | |
{ | |
if ($handle !== null) { | |
$assoc = $this->_get_assoc($server_url, $handle); | |
$assocs = array(); | |
if ($assoc) { | |
$assocs[] = $assoc; | |
} | |
} else { | |
$assocs = $this->_get_assocs($server_url); | |
} | |
if (!$assocs || (count($assocs) == 0)) { | |
return null; | |
} else { | |
$associations = array(); | |
foreach ($assocs as $assoc_row) { | |
$assoc = new Auth_OpenID_Association($assoc_row['handle'], | |
$assoc_row['secret'], | |
$assoc_row['issued'], | |
$assoc_row['lifetime'], | |
$assoc_row['assoc_type']); | |
$assoc->secret = $this->blobDecode($assoc->secret); | |
if ($assoc->getExpiresIn() == 0) { | |
$this->removeAssociation($server_url, $assoc->handle); | |
} else { | |
$associations[] = array($assoc->issued, $assoc); | |
} | |
} | |
if ($associations) { | |
$issued = array(); | |
$assocs = array(); | |
foreach ($associations as $key => $assoc) { | |
$issued[$key] = $assoc[0]; | |
$assocs[$key] = $assoc[1]; | |
} | |
array_multisort($issued, SORT_DESC, $assocs, SORT_DESC, | |
$associations); | |
// return the most recently issued one. | |
list($issued, $assoc) = $associations[0]; | |
return $assoc; | |
} else { | |
return null; | |
} | |
} | |
} | |
/** | |
* @access private | |
*/ | |
function _add_nonce($server_url, $timestamp, $salt) | |
{ | |
$sql = $this->sql['add_nonce']; | |
$result = $this->connection->query($sql, array($server_url, | |
$timestamp, | |
$salt)); | |
if ($this->isError($result)) { | |
$this->connection->rollback(); | |
} else { | |
$this->connection->commit(); | |
} | |
return $this->resultToBool($result); | |
} | |
function useNonce($server_url, $timestamp, $salt) | |
{ | |
global $Auth_OpenID_SKEW; | |
if ( abs($timestamp - time()) > $Auth_OpenID_SKEW ) { | |
return false; | |
} | |
return $this->_add_nonce($server_url, $timestamp, $salt); | |
} | |
/** | |
* "Octifies" a binary string by returning a string with escaped | |
* octal bytes. This is used for preparing binary data for | |
* PostgreSQL BYTEA fields. | |
* | |
* @access private | |
*/ | |
function _octify($str) | |
{ | |
$result = ""; | |
for ($i = 0; $i < Auth_OpenID::bytes($str); $i++) { | |
$ch = substr($str, $i, 1); | |
if ($ch == "\\") { | |
$result .= "\\\\\\\\"; | |
} else if (ord($ch) == 0) { | |
$result .= "\\\\000"; | |
} else { | |
$result .= "\\" . strval(decoct(ord($ch))); | |
} | |
} | |
return $result; | |
} | |
/** | |
* "Unoctifies" octal-escaped data from PostgreSQL and returns the | |
* resulting ASCII (possibly binary) string. | |
* | |
* @access private | |
*/ | |
function _unoctify($str) | |
{ | |
$result = ""; | |
$i = 0; | |
while ($i < strlen($str)) { | |
$char = $str[$i]; | |
if ($char == "\\") { | |
// Look to see if the next char is a backslash and | |
// append it. | |
if ($str[$i + 1] != "\\") { | |
$octal_digits = substr($str, $i + 1, 3); | |
$dec = octdec($octal_digits); | |
$char = chr($dec); | |
$i += 4; | |
} else { | |
$char = "\\"; | |
$i += 2; | |
} | |
} else { | |
$i += 1; | |
} | |
$result .= $char; | |
} | |
return $result; | |
} | |
function cleanupNonces() | |
{ | |
global $Auth_OpenID_SKEW; | |
$v = time() - $Auth_OpenID_SKEW; | |
$this->connection->query($this->sql['clean_nonce'], array($v)); | |
$num = $this->connection->affectedRows(); | |
$this->connection->commit(); | |
return $num; | |
} | |
function cleanupAssociations() | |
{ | |
$this->connection->query($this->sql['clean_assoc'], | |
array(time())); | |
$num = $this->connection->affectedRows(); | |
$this->connection->commit(); | |
return $num; | |
} | |
} | |
<?php | |
/** | |
* An SQLite store. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Require the base class file. | |
*/ | |
require_once "Auth/OpenID/SQLStore.php"; | |
/** | |
* An SQL store that uses SQLite as its backend. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_SQLiteStore extends Auth_OpenID_SQLStore { | |
function setSQL() | |
{ | |
$this->sql['nonce_table'] = | |
"CREATE TABLE %s (server_url VARCHAR(2047), timestamp INTEGER, ". | |
"salt CHAR(40), UNIQUE (server_url, timestamp, salt))"; | |
$this->sql['assoc_table'] = | |
"CREATE TABLE %s (server_url VARCHAR(2047), handle VARCHAR(255), ". | |
"secret BLOB(128), issued INTEGER, lifetime INTEGER, ". | |
"assoc_type VARCHAR(64), PRIMARY KEY (server_url, handle))"; | |
$this->sql['set_assoc'] = | |
"INSERT OR REPLACE INTO %s VALUES (?, ?, ?, ?, ?, ?)"; | |
$this->sql['get_assocs'] = | |
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". | |
"WHERE server_url = ?"; | |
$this->sql['get_assoc'] = | |
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ". | |
"WHERE server_url = ? AND handle = ?"; | |
$this->sql['remove_assoc'] = | |
"DELETE FROM %s WHERE server_url = ? AND handle = ?"; | |
$this->sql['add_nonce'] = | |
"INSERT INTO %s (server_url, timestamp, salt) VALUES (?, ?, ?)"; | |
$this->sql['clean_nonce'] = | |
"DELETE FROM %s WHERE timestamp < ?"; | |
$this->sql['clean_assoc'] = | |
"DELETE FROM %s WHERE issued + lifetime < ?"; | |
} | |
/** | |
* @access private | |
*/ | |
function _add_nonce($server_url, $timestamp, $salt) | |
{ | |
// PECL SQLite extensions 1.0.3 and older (1.0.3 is the | |
// current release at the time of this writing) have a broken | |
// sqlite_escape_string function that breaks when passed the | |
// empty string. Prefixing all strings with one character | |
// keeps them unique and avoids this bug. The nonce table is | |
// write-only, so we don't have to worry about updating other | |
// functions with this same bad hack. | |
return parent::_add_nonce('x' . $server_url, $timestamp, $salt); | |
} | |
} | |
<?php | |
/** | |
* Simple registration request and response parsing and object | |
* representation. | |
* | |
* This module contains objects representing simple registration | |
* requests and responses that can be used with both OpenID relying | |
* parties and OpenID providers. | |
* | |
* 1. The relying party creates a request object and adds it to the | |
* {@link Auth_OpenID_AuthRequest} object before making the | |
* checkid request to the OpenID provider: | |
* | |
* $sreg_req = Auth_OpenID_SRegRequest::build(array('email')); | |
* $auth_request->addExtension($sreg_req); | |
* | |
* 2. The OpenID provider extracts the simple registration request | |
* from the OpenID request using {@link | |
* Auth_OpenID_SRegRequest::fromOpenIDRequest}, gets the user's | |
* approval and data, creates an {@link Auth_OpenID_SRegResponse} | |
* object and adds it to the id_res response: | |
* | |
* $sreg_req = Auth_OpenID_SRegRequest::fromOpenIDRequest( | |
* $checkid_request); | |
* // [ get the user's approval and data, informing the user that | |
* // the fields in sreg_response were requested ] | |
* $sreg_resp = Auth_OpenID_SRegResponse::extractResponse( | |
* $sreg_req, $user_data); | |
* $sreg_resp->toMessage($openid_response->fields); | |
* | |
* 3. The relying party uses {@link | |
* Auth_OpenID_SRegResponse::fromSuccessResponse} to extract the data | |
* from the OpenID response: | |
* | |
* $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse( | |
* $success_response); | |
* | |
* @package OpenID | |
*/ | |
/** | |
* Import message and extension internals. | |
*/ | |
require_once 'Auth/OpenID/Message.php'; | |
require_once 'Auth/OpenID/Extension.php'; | |
// The data fields that are listed in the sreg spec | |
global $Auth_OpenID_sreg_data_fields; | |
$Auth_OpenID_sreg_data_fields = array( | |
'fullname' => 'Full Name', | |
'nickname' => 'Nickname', | |
'dob' => 'Date of Birth', | |
'email' => 'E-mail Address', | |
'gender' => 'Gender', | |
'postcode' => 'Postal Code', | |
'country' => 'Country', | |
'language' => 'Language', | |
'timezone' => 'Time Zone'); | |
/** | |
* Check to see that the given value is a valid simple registration | |
* data field name. Return true if so, false if not. | |
*/ | |
function Auth_OpenID_checkFieldName($field_name) | |
{ | |
global $Auth_OpenID_sreg_data_fields; | |
if (!in_array($field_name, array_keys($Auth_OpenID_sreg_data_fields))) { | |
return false; | |
} | |
return true; | |
} | |
// URI used in the wild for Yadis documents advertising simple | |
// registration support | |
define('Auth_OpenID_SREG_NS_URI_1_0', 'http://openid.net/sreg/1.0'); | |
// URI in the draft specification for simple registration 1.1 | |
// <http://openid.net/specs/openid-simple-registration-extension-1_1-01.html> | |
define('Auth_OpenID_SREG_NS_URI_1_1', 'http://openid.net/extensions/sreg/1.1'); | |
// This attribute will always hold the preferred URI to use when | |
// adding sreg support to an XRDS file or in an OpenID namespace | |
// declaration. | |
define('Auth_OpenID_SREG_NS_URI', Auth_OpenID_SREG_NS_URI_1_1); | |
Auth_OpenID_registerNamespaceAlias(Auth_OpenID_SREG_NS_URI_1_1, 'sreg'); | |
/** | |
* Does the given endpoint advertise support for simple | |
* registration? | |
* | |
* $endpoint: The endpoint object as returned by OpenID discovery. | |
* returns whether an sreg type was advertised by the endpoint | |
*/ | |
function Auth_OpenID_supportsSReg($endpoint) | |
{ | |
return ($endpoint->usesExtension(Auth_OpenID_SREG_NS_URI_1_1) || | |
$endpoint->usesExtension(Auth_OpenID_SREG_NS_URI_1_0)); | |
} | |
/** | |
* A base class for classes dealing with Simple Registration protocol | |
* messages. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_SRegBase extends Auth_OpenID_Extension { | |
/** | |
* Extract the simple registration namespace URI from the given | |
* OpenID message. Handles OpenID 1 and 2, as well as both sreg | |
* namespace URIs found in the wild, as well as missing namespace | |
* definitions (for OpenID 1) | |
* | |
* $message: The OpenID message from which to parse simple | |
* registration fields. This may be a request or response message. | |
* | |
* Returns the sreg namespace URI for the supplied message. The | |
* message may be modified to define a simple registration | |
* namespace. | |
* | |
* @access private | |
*/ | |
static function _getSRegNS($message) | |
{ | |
$alias = null; | |
$found_ns_uri = null; | |
// See if there exists an alias for one of the two defined | |
// simple registration types. | |
foreach (array(Auth_OpenID_SREG_NS_URI_1_1, | |
Auth_OpenID_SREG_NS_URI_1_0) as $sreg_ns_uri) { | |
$alias = $message->namespaces->getAlias($sreg_ns_uri); | |
if ($alias !== null) { | |
$found_ns_uri = $sreg_ns_uri; | |
break; | |
} | |
} | |
if ($alias === null) { | |
// There is no alias for either of the types, so try to | |
// add one. We default to using the modern value (1.1) | |
$found_ns_uri = Auth_OpenID_SREG_NS_URI_1_1; | |
if ($message->namespaces->addAlias(Auth_OpenID_SREG_NS_URI_1_1, | |
'sreg') === null) { | |
// An alias for the string 'sreg' already exists, but | |
// it's defined for something other than simple | |
// registration | |
return null; | |
} | |
} | |
return $found_ns_uri; | |
} | |
} | |
/** | |
* An object to hold the state of a simple registration request. | |
* | |
* required: A list of the required fields in this simple registration | |
* request | |
* | |
* optional: A list of the optional fields in this simple registration | |
* request | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_SRegRequest extends Auth_OpenID_SRegBase { | |
var $ns_alias = 'sreg'; | |
/** | |
* Initialize an empty simple registration request. | |
*/ | |
static function build($required=null, $optional=null, | |
$policy_url=null, | |
$sreg_ns_uri=Auth_OpenID_SREG_NS_URI, | |
$cls='Auth_OpenID_SRegRequest') | |
{ | |
$obj = new $cls(); | |
$obj->required = array(); | |
$obj->optional = array(); | |
$obj->policy_url = $policy_url; | |
$obj->ns_uri = $sreg_ns_uri; | |
if ($required) { | |
if (!$obj->requestFields($required, true, true)) { | |
return null; | |
} | |
} | |
if ($optional) { | |
if (!$obj->requestFields($optional, false, true)) { | |
return null; | |
} | |
} | |
return $obj; | |
} | |
/** | |
* Create a simple registration request that contains the fields | |
* that were requested in the OpenID request with the given | |
* arguments | |
* | |
* $request: The OpenID authentication request from which to | |
* extract an sreg request. | |
* | |
* $cls: name of class to use when creating sreg request object. | |
* Used for testing. | |
* | |
* Returns the newly created simple registration request | |
*/ | |
static function fromOpenIDRequest($request, $cls='Auth_OpenID_SRegRequest') | |
{ | |
$obj = call_user_func_array(array($cls, 'build'), | |
array(null, null, null, Auth_OpenID_SREG_NS_URI, $cls)); | |
// Since we're going to mess with namespace URI mapping, don't | |
// mutate the object that was passed in. | |
$m = $request->message; | |
$obj->ns_uri = $obj->_getSRegNS($m); | |
$args = $m->getArgs($obj->ns_uri); | |
if ($args === null || Auth_OpenID::isFailure($args)) { | |
return null; | |
} | |
$obj->parseExtensionArgs($args); | |
return $obj; | |
} | |
/** | |
* Parse the unqualified simple registration request parameters | |
* and add them to this object. | |
* | |
* This method is essentially the inverse of | |
* getExtensionArgs. This method restores the serialized simple | |
* registration request fields. | |
* | |
* If you are extracting arguments from a standard OpenID | |
* checkid_* request, you probably want to use fromOpenIDRequest, | |
* which will extract the sreg namespace and arguments from the | |
* OpenID request. This method is intended for cases where the | |
* OpenID server needs more control over how the arguments are | |
* parsed than that method provides. | |
* | |
* $args == $message->getArgs($ns_uri); | |
* $request->parseExtensionArgs($args); | |
* | |
* $args: The unqualified simple registration arguments | |
* | |
* strict: Whether requests with fields that are not defined in | |
* the simple registration specification should be tolerated (and | |
* ignored) | |
*/ | |
function parseExtensionArgs($args, $strict=false) | |
{ | |
foreach (array('required', 'optional') as $list_name) { | |
$required = ($list_name == 'required'); | |
$items = Auth_OpenID::arrayGet($args, $list_name); | |
if ($items) { | |
foreach (explode(',', $items) as $field_name) { | |
if (!$this->requestField($field_name, $required, $strict)) { | |
if ($strict) { | |
return false; | |
} | |
} | |
} | |
} | |
} | |
$this->policy_url = Auth_OpenID::arrayGet($args, 'policy_url'); | |
return true; | |
} | |
/** | |
* A list of all of the simple registration fields that were | |
* requested, whether they were required or optional. | |
*/ | |
function allRequestedFields() | |
{ | |
return array_merge($this->required, $this->optional); | |
} | |
/** | |
* Have any simple registration fields been requested? | |
*/ | |
function wereFieldsRequested() | |
{ | |
return count($this->allRequestedFields()); | |
} | |
/** | |
* Was this field in the request? | |
*/ | |
function contains($field_name) | |
{ | |
return (in_array($field_name, $this->required) || | |
in_array($field_name, $this->optional)); | |
} | |
/** | |
* Request the specified field from the OpenID user | |
* | |
* $field_name: the unqualified simple registration field name | |
* | |
* required: whether the given field should be presented to the | |
* user as being a required to successfully complete the request | |
* | |
* strict: whether to raise an exception when a field is added to | |
* a request more than once | |
*/ | |
function requestField($field_name, | |
$required=false, $strict=false) | |
{ | |
if (!Auth_OpenID_checkFieldName($field_name)) { | |
return false; | |
} | |
if ($strict) { | |
if ($this->contains($field_name)) { | |
return false; | |
} | |
} else { | |
if (in_array($field_name, $this->required)) { | |
return true; | |
} | |
if (in_array($field_name, $this->optional)) { | |
if ($required) { | |
unset($this->optional[array_search($field_name, | |
$this->optional)]); | |
} else { | |
return true; | |
} | |
} | |
} | |
if ($required) { | |
$this->required[] = $field_name; | |
} else { | |
$this->optional[] = $field_name; | |
} | |
return true; | |
} | |
/** | |
* Add the given list of fields to the request | |
* | |
* field_names: The simple registration data fields to request | |
* | |
* required: Whether these values should be presented to the user | |
* as required | |
* | |
* strict: whether to raise an exception when a field is added to | |
* a request more than once | |
*/ | |
function requestFields($field_names, $required=false, $strict=false) | |
{ | |
if (!is_array($field_names)) { | |
return false; | |
} | |
foreach ($field_names as $field_name) { | |
if (!$this->requestField($field_name, $required, $strict=$strict)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Get a dictionary of unqualified simple registration arguments | |
* representing this request. | |
* | |
* This method is essentially the inverse of | |
* C{L{parseExtensionArgs}}. This method serializes the simple | |
* registration request fields. | |
*/ | |
function getExtensionArgs() | |
{ | |
$args = array(); | |
if ($this->required) { | |
$args['required'] = implode(',', $this->required); | |
} | |
if ($this->optional) { | |
$args['optional'] = implode(',', $this->optional); | |
} | |
if ($this->policy_url) { | |
$args['policy_url'] = $this->policy_url; | |
} | |
return $args; | |
} | |
} | |
/** | |
* Represents the data returned in a simple registration response | |
* inside of an OpenID C{id_res} response. This object will be created | |
* by the OpenID server, added to the C{id_res} response object, and | |
* then extracted from the C{id_res} message by the Consumer. | |
* | |
* @package OpenID | |
*/ | |
class Auth_OpenID_SRegResponse extends Auth_OpenID_SRegBase { | |
var $ns_alias = 'sreg'; | |
function Auth_OpenID_SRegResponse($data=null, | |
$sreg_ns_uri=Auth_OpenID_SREG_NS_URI) | |
{ | |
if ($data === null) { | |
$this->data = array(); | |
} else { | |
$this->data = $data; | |
} | |
$this->ns_uri = $sreg_ns_uri; | |
} | |
/** | |
* Take a C{L{SRegRequest}} and a dictionary of simple | |
* registration values and create a C{L{SRegResponse}} object | |
* containing that data. | |
* | |
* request: The simple registration request object | |
* | |
* data: The simple registration data for this response, as a | |
* dictionary from unqualified simple registration field name to | |
* string (unicode) value. For instance, the nickname should be | |
* stored under the key 'nickname'. | |
*/ | |
static function extractResponse($request, $data) | |
{ | |
$obj = new Auth_OpenID_SRegResponse(); | |
$obj->ns_uri = $request->ns_uri; | |
foreach ($request->allRequestedFields() as $field) { | |
$value = Auth_OpenID::arrayGet($data, $field); | |
if ($value !== null) { | |
$obj->data[$field] = $value; | |
} | |
} | |
return $obj; | |
} | |
/** | |
* Create a C{L{SRegResponse}} object from a successful OpenID | |
* library response | |
* (C{L{openid.consumer.consumer.SuccessResponse}}) response | |
* message | |
* | |
* success_response: A SuccessResponse from consumer.complete() | |
* | |
* signed_only: Whether to process only data that was | |
* signed in the id_res message from the server. | |
* | |
* Returns a simple registration response containing the data that | |
* was supplied with the C{id_res} response. | |
*/ | |
static function fromSuccessResponse($success_response, $signed_only=true) | |
{ | |
global $Auth_OpenID_sreg_data_fields; | |
$obj = new Auth_OpenID_SRegResponse(); | |
$obj->ns_uri = $obj->_getSRegNS($success_response->message); | |
if ($signed_only) { | |
$args = $success_response->getSignedNS($obj->ns_uri); | |
} else { | |
$args = $success_response->message->getArgs($obj->ns_uri); | |
} | |
if ($args === null || Auth_OpenID::isFailure($args)) { | |
return null; | |
} | |
foreach ($Auth_OpenID_sreg_data_fields as $field_name => $desc) { | |
if (in_array($field_name, array_keys($args))) { | |
$obj->data[$field_name] = $args[$field_name]; | |
} | |
} | |
return $obj; | |
} | |
function getExtensionArgs() | |
{ | |
return $this->data; | |
} | |
// Read-only dictionary interface | |
function get($field_name, $default=null) | |
{ | |
if (!Auth_OpenID_checkFieldName($field_name)) { | |
return null; | |
} | |
return Auth_OpenID::arrayGet($this->data, $field_name, $default); | |
} | |
function contents() | |
{ | |
return $this->data; | |
} | |
} | |
<?php | <?php |
/** | /** |
* OpenID server protocol and logic. | * OpenID server protocol and logic. |
* | * |
* Overview | * Overview |
* | * |
* An OpenID server must perform three tasks: | * An OpenID server must perform three tasks: |
* | * |
* 1. Examine the incoming request to determine its nature and validity. | * 1. Examine the incoming request to determine its nature and validity. |
* 2. Make a decision about how to respond to this request. | * 2. Make a decision about how to respond to this request. |
* 3. Format the response according to the protocol. | * 3. Format the response according to the protocol. |
* | * |
* The first and last of these tasks may performed by the {@link | * The first and last of these tasks may performed by the {@link |
* Auth_OpenID_Server::decodeRequest()} and {@link | * Auth_OpenID_Server::decodeRequest()} and {@link |
* Auth_OpenID_Server::encodeResponse} methods. Who gets to do the | * Auth_OpenID_Server::encodeResponse} methods. Who gets to do the |
* intermediate task -- deciding how to respond to the request -- will | * intermediate task -- deciding how to respond to the request -- will |
* depend on what type of request it is. | * depend on what type of request it is. |
* | * |
* If it's a request to authenticate a user (a 'checkid_setup' or | * If it's a request to authenticate a user (a 'checkid_setup' or |
* 'checkid_immediate' request), you need to decide if you will assert | * 'checkid_immediate' request), you need to decide if you will assert |
* that this user may claim the identity in question. Exactly how you | * that this user may claim the identity in question. Exactly how you |
* do that is a matter of application policy, but it generally | * do that is a matter of application policy, but it generally |
* involves making sure the user has an account with your system and | * involves making sure the user has an account with your system and |
* is logged in, checking to see if that identity is hers to claim, | * is logged in, checking to see if that identity is hers to claim, |
* and verifying with the user that she does consent to releasing that | * and verifying with the user that she does consent to releasing that |
* information to the party making the request. | * information to the party making the request. |
* | * |
* Examine the properties of the {@link Auth_OpenID_CheckIDRequest} | * Examine the properties of the {@link Auth_OpenID_CheckIDRequest} |
* object, and if and when you've come to a decision, form a response | * object, and if and when you've come to a decision, form a response |
* by calling {@link Auth_OpenID_CheckIDRequest::answer()}. | * by calling {@link Auth_OpenID_CheckIDRequest::answer()}. |
* | * |
* Other types of requests relate to establishing associations between | * Other types of requests relate to establishing associations between |
* client and server and verifing the authenticity of previous | * client and server and verifing the authenticity of previous |
* communications. {@link Auth_OpenID_Server} contains all the logic | * communications. {@link Auth_OpenID_Server} contains all the logic |
* and data necessary to respond to such requests; just pass it to | * and data necessary to respond to such requests; just pass it to |
* {@link Auth_OpenID_Server::handleRequest()}. | * {@link Auth_OpenID_Server::handleRequest()}. |
* | * |
* OpenID Extensions | * OpenID Extensions |
* | * |
* Do you want to provide other information for your users in addition | * Do you want to provide other information for your users in addition |
* to authentication? Version 1.2 of the OpenID protocol allows | * to authentication? Version 1.2 of the OpenID protocol allows |
* consumers to add extensions to their requests. For example, with | * consumers to add extensions to their requests. For example, with |
* sites using the Simple Registration | * sites using the Simple Registration |
* Extension | * Extension |
* (http://openid.net/specs/openid-simple-registration-extension-1_0.html), | * (http://openid.net/specs/openid-simple-registration-extension-1_0.html), |
* a user can agree to have their nickname and e-mail address sent to | * a user can agree to have their nickname and e-mail address sent to |
* a site when they sign up. | * a site when they sign up. |
* | * |
* Since extensions do not change the way OpenID authentication works, | * Since extensions do not change the way OpenID authentication works, |
* code to handle extension requests may be completely separate from | * code to handle extension requests may be completely separate from |
* the {@link Auth_OpenID_Request} class here. But you'll likely want | * the {@link Auth_OpenID_Request} class here. But you'll likely want |
* data sent back by your extension to be signed. {@link | * data sent back by your extension to be signed. {@link |
* Auth_OpenID_ServerResponse} provides methods with which you can add | * Auth_OpenID_ServerResponse} provides methods with which you can add |
* data to it which can be signed with the other data in the OpenID | * data to it which can be signed with the other data in the OpenID |
* signature. | * signature. |
* | * |
* For example: | * For example: |
* | * |
* <pre> // when request is a checkid_* request | * <pre> // when request is a checkid_* request |
* $response = $request->answer(true); | * $response = $request->answer(true); |
* // this will a signed 'openid.sreg.timezone' parameter to the response | * // this will a signed 'openid.sreg.timezone' parameter to the response |
* response.addField('sreg', 'timezone', 'America/Los_Angeles')</pre> | * response.addField('sreg', 'timezone', 'America/Los_Angeles')</pre> |
* | * |
* Stores | * Stores |
* | * |
* The OpenID server needs to maintain state between requests in order | * The OpenID server needs to maintain state between requests in order |
* to function. Its mechanism for doing this is called a store. The | * to function. Its mechanism for doing this is called a store. The |
* store interface is defined in Interface.php. Additionally, several | * store interface is defined in Interface.php. Additionally, several |
* concrete store implementations are provided, so that most sites | * concrete store implementations are provided, so that most sites |
* won't need to implement a custom store. For a store backed by flat | * won't need to implement a custom store. For a store backed by flat |
* files on disk, see {@link Auth_OpenID_FileStore}. For stores based | * files on disk, see {@link Auth_OpenID_FileStore}. For stores based |
* on MySQL, SQLite, or PostgreSQL, see the {@link | * on MySQL, SQLite, or PostgreSQL, see the {@link |
* Auth_OpenID_SQLStore} subclasses. | * Auth_OpenID_SQLStore} subclasses. |
* | * |
* Upgrading | * Upgrading |
* | * |
* The keys by which a server looks up associations in its store have | * The keys by which a server looks up associations in its store have |
* changed in version 1.2 of this library. If your store has entries | * changed in version 1.2 of this library. If your store has entries |
* created from version 1.0 code, you should empty it. | * created from version 1.0 code, you should empty it. |
* | * |
* PHP versions 4 and 5 | * PHP versions 4 and 5 |
* | * |
* LICENSE: See the COPYING file included in this distribution. | * LICENSE: See the COPYING file included in this distribution. |
* | * |
* @package OpenID | * @package OpenID |
* @author JanRain, Inc. <openid@janrain.com> | * @author JanRain, Inc. <openid@janrain.com> |
* @copyright 2005-2008 Janrain, Inc. | * @copyright 2005-2008 Janrain, Inc. |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache |
*/ | */ |
/** | /** |
* Required imports | * Required imports |
*/ | */ |
require_once "Auth/OpenID.php"; | require_once "Auth/OpenID.php"; |
require_once "Auth/OpenID/Association.php"; | require_once "Auth/OpenID/Association.php"; |
require_once "Auth/OpenID/CryptUtil.php"; | require_once "Auth/OpenID/CryptUtil.php"; |
require_once "Auth/OpenID/BigMath.php"; | require_once "Auth/OpenID/BigMath.php"; |
require_once "Auth/OpenID/DiffieHellman.php"; | require_once "Auth/OpenID/DiffieHellman.php"; |
require_once "Auth/OpenID/KVForm.php"; | require_once "Auth/OpenID/KVForm.php"; |
require_once "Auth/OpenID/TrustRoot.php"; | require_once "Auth/OpenID/TrustRoot.php"; |
require_once "Auth/OpenID/ServerRequest.php"; | require_once "Auth/OpenID/ServerRequest.php"; |
require_once "Auth/OpenID/Message.php"; | require_once "Auth/OpenID/Message.php"; |
require_once "Auth/OpenID/Nonce.php"; | require_once "Auth/OpenID/Nonce.php"; |
define('AUTH_OPENID_HTTP_OK', 200); | define('AUTH_OPENID_HTTP_OK', 200); |
define('AUTH_OPENID_HTTP_REDIRECT', 302); | define('AUTH_OPENID_HTTP_REDIRECT', 302); |
define('AUTH_OPENID_HTTP_ERROR', 400); | define('AUTH_OPENID_HTTP_ERROR', 400); |
/** | /** |
* @access private | * @access private |
*/ | */ |
global $_Auth_OpenID_Request_Modes; | global $_Auth_OpenID_Request_Modes; |
$_Auth_OpenID_Request_Modes = array('checkid_setup', | $_Auth_OpenID_Request_Modes = array('checkid_setup', |
'checkid_immediate'); | 'checkid_immediate'); |
/** | /** |
* @access private | * @access private |
*/ | */ |
define('Auth_OpenID_ENCODE_KVFORM', 'kfvorm'); | define('Auth_OpenID_ENCODE_KVFORM', 'kfvorm'); |
/** | /** |
* @access private | * @access private |
*/ | */ |
define('Auth_OpenID_ENCODE_URL', 'URL/redirect'); | define('Auth_OpenID_ENCODE_URL', 'URL/redirect'); |
/** | /** |
* @access private | * @access private |
*/ | */ |
define('Auth_OpenID_ENCODE_HTML_FORM', 'HTML form'); | define('Auth_OpenID_ENCODE_HTML_FORM', 'HTML form'); |
/** | /** |
* @access private | * @access private |
*/ | */ |
function Auth_OpenID_isError($obj, $cls = 'Auth_OpenID_ServerError') | function Auth_OpenID_isError($obj, $cls = 'Auth_OpenID_ServerError') |
{ | { |
return is_a($obj, $cls); | return is_a($obj, $cls); |
} | } |
/** | /** |
* An error class which gets instantiated and returned whenever an | * An error class which gets instantiated and returned whenever an |
* OpenID protocol error occurs. Be prepared to use this in place of | * OpenID protocol error occurs. Be prepared to use this in place of |
* an ordinary server response. | * an ordinary server response. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_ServerError { | class Auth_OpenID_ServerError { |
/** | /** |
* @access private | * @access private |
*/ | */ |
function Auth_OpenID_ServerError($message = null, $text = null, | function Auth_OpenID_ServerError($message = null, $text = null, |
$reference = null, $contact = null) | $reference = null, $contact = null) |
{ | { |
$this->message = $message; | $this->message = $message; |
$this->text = $text; | $this->text = $text; |
$this->contact = $contact; | $this->contact = $contact; |
$this->reference = $reference; | $this->reference = $reference; |
} | } |
function getReturnTo() | function getReturnTo() |
{ | { |
if ($this->message && | if ($this->message && |
$this->message->hasKey(Auth_OpenID_OPENID_NS, 'return_to')) { | $this->message->hasKey(Auth_OpenID_OPENID_NS, 'return_to')) { |
return $this->message->getArg(Auth_OpenID_OPENID_NS, | return $this->message->getArg(Auth_OpenID_OPENID_NS, |
'return_to'); | 'return_to'); |
} else { | } else { |
return null; | return null; |
} | } |
} | } |
/** | /** |
* Returns the return_to URL for the request which caused this | * Returns the return_to URL for the request which caused this |
* error. | * error. |
*/ | */ |
function hasReturnTo() | function hasReturnTo() |
{ | { |
return $this->getReturnTo() !== null; | return $this->getReturnTo() !== null; |
} | } |
/** | /** |
* Encodes this error's response as a URL suitable for | * Encodes this error's response as a URL suitable for |
* redirection. If the response has no return_to, another | * redirection. If the response has no return_to, another |
* Auth_OpenID_ServerError is returned. | * Auth_OpenID_ServerError is returned. |
*/ | */ |
function encodeToURL() | function encodeToURL() |
{ | { |
if (!$this->message) { | if (!$this->message) { |
return null; | return null; |
} | } |
$msg = $this->toMessage(); | $msg = $this->toMessage(); |
return $msg->toURL($this->getReturnTo()); | return $msg->toURL($this->getReturnTo()); |
} | } |
/** | /** |
* Encodes the response to key-value form. This is a | * Encodes the response to key-value form. This is a |
* machine-readable format used to respond to messages which came | * machine-readable format used to respond to messages which came |
* directly from the consumer and not through the user-agent. See | * directly from the consumer and not through the user-agent. See |
* the OpenID specification. | * the OpenID specification. |
*/ | */ |
function encodeToKVForm() | function encodeToKVForm() |
{ | { |
return Auth_OpenID_KVForm::fromArray( | return Auth_OpenID_KVForm::fromArray( |
array('mode' => 'error', | array('mode' => 'error', |
'error' => $this->toString())); | 'error' => $this->toString())); |
} | } |
function toFormMarkup($form_tag_attrs=null) | function toFormMarkup($form_tag_attrs=null) |
{ | { |
$msg = $this->toMessage(); | $msg = $this->toMessage(); |
return $msg->toFormMarkup($this->getReturnTo(), $form_tag_attrs); | return $msg->toFormMarkup($this->getReturnTo(), $form_tag_attrs); |
} | } |
function toHTML($form_tag_attrs=null) | function toHTML($form_tag_attrs=null) |
{ | { |
return Auth_OpenID::autoSubmitHTML( | return Auth_OpenID::autoSubmitHTML( |
$this->toFormMarkup($form_tag_attrs)); | $this->toFormMarkup($form_tag_attrs)); |
} | } |
function toMessage() | function toMessage() |
{ | { |
// Generate a Message object for sending to the relying party, | // Generate a Message object for sending to the relying party, |
// after encoding. | // after encoding. |
$namespace = $this->message->getOpenIDNamespace(); | $namespace = $this->message->getOpenIDNamespace(); |
$reply = new Auth_OpenID_Message($namespace); | $reply = new Auth_OpenID_Message($namespace); |
$reply->setArg(Auth_OpenID_OPENID_NS, 'mode', 'error'); | $reply->setArg(Auth_OpenID_OPENID_NS, 'mode', 'error'); |
$reply->setArg(Auth_OpenID_OPENID_NS, 'error', $this->toString()); | $reply->setArg(Auth_OpenID_OPENID_NS, 'error', $this->toString()); |
if ($this->contact !== null) { | if ($this->contact !== null) { |
$reply->setArg(Auth_OpenID_OPENID_NS, 'contact', $this->contact); | $reply->setArg(Auth_OpenID_OPENID_NS, 'contact', $this->contact); |
} | } |
if ($this->reference !== null) { | if ($this->reference !== null) { |
$reply->setArg(Auth_OpenID_OPENID_NS, 'reference', | $reply->setArg(Auth_OpenID_OPENID_NS, 'reference', |
$this->reference); | $this->reference); |
} | } |
return $reply; | return $reply; |
} | } |
/** | /** |
* Returns one of Auth_OpenID_ENCODE_URL, | * Returns one of Auth_OpenID_ENCODE_URL, |
* Auth_OpenID_ENCODE_KVFORM, or null, depending on the type of | * Auth_OpenID_ENCODE_KVFORM, or null, depending on the type of |
* encoding expected for this error's payload. | * encoding expected for this error's payload. |
*/ | */ |
function whichEncoding() | function whichEncoding() |
{ | { |
global $_Auth_OpenID_Request_Modes; | global $_Auth_OpenID_Request_Modes; |
if ($this->hasReturnTo()) { | if ($this->hasReturnTo()) { |
if ($this->message->isOpenID2() && | if ($this->message->isOpenID2() && |
(strlen($this->encodeToURL()) > | (strlen($this->encodeToURL()) > |
Auth_OpenID_OPENID1_URL_LIMIT)) { | Auth_OpenID_OPENID1_URL_LIMIT)) { |
return Auth_OpenID_ENCODE_HTML_FORM; | return Auth_OpenID_ENCODE_HTML_FORM; |
} else { | } else { |
return Auth_OpenID_ENCODE_URL; | return Auth_OpenID_ENCODE_URL; |
} | } |
} | } |
if (!$this->message) { | if (!$this->message) { |
return null; | return null; |
} | } |
$mode = $this->message->getArg(Auth_OpenID_OPENID_NS, | $mode = $this->message->getArg(Auth_OpenID_OPENID_NS, |
'mode'); | 'mode'); |
if ($mode) { | if ($mode) { |
if (!in_array($mode, $_Auth_OpenID_Request_Modes)) { | if (!in_array($mode, $_Auth_OpenID_Request_Modes)) { |
return Auth_OpenID_ENCODE_KVFORM; | return Auth_OpenID_ENCODE_KVFORM; |
} | } |
} | } |
return null; | return null; |
} | } |
/** | /** |
* Returns this error message. | * Returns this error message. |
*/ | */ |
function toString() | function toString() |
{ | { |
if ($this->text) { | if ($this->text) { |
return $this->text; | return $this->text; |
} else { | } else { |
return get_class($this) . " error"; | return get_class($this) . " error"; |
} | } |
} | } |
} | } |
/** | /** |
* Error returned by the server code when a return_to is absent from a | * Error returned by the server code when a return_to is absent from a |
* request. | * request. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_NoReturnToError extends Auth_OpenID_ServerError { | class Auth_OpenID_NoReturnToError extends Auth_OpenID_ServerError { |
function Auth_OpenID_NoReturnToError($message = null, | function Auth_OpenID_NoReturnToError($message = null, |
$text = "No return_to URL available") | $text = "No return_to URL available") |
{ | { |
parent::Auth_OpenID_ServerError($message, $text); | parent::Auth_OpenID_ServerError($message, $text); |
} | } |
function toString() | function toString() |
{ | { |
return "No return_to available"; | return "No return_to available"; |
} | } |
} | } |
/** | /** |
* An error indicating that the return_to URL is malformed. | * An error indicating that the return_to URL is malformed. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_MalformedReturnURL extends Auth_OpenID_ServerError { | class Auth_OpenID_MalformedReturnURL extends Auth_OpenID_ServerError { |
function Auth_OpenID_MalformedReturnURL($message, $return_to) | function Auth_OpenID_MalformedReturnURL($message, $return_to) |
{ | { |
$this->return_to = $return_to; | $this->return_to = $return_to; |
parent::Auth_OpenID_ServerError($message, "malformed return_to URL"); | parent::Auth_OpenID_ServerError($message, "malformed return_to URL"); |
} | } |
} | } |
/** | /** |
* This error is returned when the trust_root value is malformed. | * This error is returned when the trust_root value is malformed. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_MalformedTrustRoot extends Auth_OpenID_ServerError { | class Auth_OpenID_MalformedTrustRoot extends Auth_OpenID_ServerError { |
function Auth_OpenID_MalformedTrustRoot($message = null, | function Auth_OpenID_MalformedTrustRoot($message = null, |
$text = "Malformed trust root") | $text = "Malformed trust root") |
{ | { |
parent::Auth_OpenID_ServerError($message, $text); | parent::Auth_OpenID_ServerError($message, $text); |
} | } |
function toString() | function toString() |
{ | { |
return "Malformed trust root"; | return "Malformed trust root"; |
} | } |
} | } |
/** | /** |
* The base class for all server request classes. | * The base class for all server request classes. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_Request { | class Auth_OpenID_Request { |
var $mode = null; | var $mode = null; |
} | } |
/** | /** |
* A request to verify the validity of a previous response. | * A request to verify the validity of a previous response. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_CheckAuthRequest extends Auth_OpenID_Request { | class Auth_OpenID_CheckAuthRequest extends Auth_OpenID_Request { |
var $mode = "check_authentication"; | var $mode = "check_authentication"; |
var $invalidate_handle = null; | var $invalidate_handle = null; |
function Auth_OpenID_CheckAuthRequest($assoc_handle, $signed, | function Auth_OpenID_CheckAuthRequest($assoc_handle, $signed, |
$invalidate_handle = null) | $invalidate_handle = null) |
{ | { |
$this->assoc_handle = $assoc_handle; | $this->assoc_handle = $assoc_handle; |
$this->signed = $signed; | $this->signed = $signed; |
if ($invalidate_handle !== null) { | if ($invalidate_handle !== null) { |
$this->invalidate_handle = $invalidate_handle; | $this->invalidate_handle = $invalidate_handle; |
} | } |
$this->namespace = Auth_OpenID_OPENID2_NS; | $this->namespace = Auth_OpenID_OPENID2_NS; |
$this->message = null; | $this->message = null; |
} | } |
static function fromMessage($message, $server=null) | static function fromMessage($message, $server=null) |
{ | { |
$required_keys = array('assoc_handle', 'sig', 'signed'); | $required_keys = array('assoc_handle', 'sig', 'signed'); |
foreach ($required_keys as $k) { | foreach ($required_keys as $k) { |
if (!$message->getArg(Auth_OpenID_OPENID_NS, $k)) { | if (!$message->getArg(Auth_OpenID_OPENID_NS, $k)) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
sprintf("%s request missing required parameter %s from \ | sprintf("%s request missing required parameter %s from \ |
query", "check_authentication", $k)); | query", "check_authentication", $k)); |
} | } |
} | } |
$assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, 'assoc_handle'); | $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, 'assoc_handle'); |
$sig = $message->getArg(Auth_OpenID_OPENID_NS, 'sig'); | $sig = $message->getArg(Auth_OpenID_OPENID_NS, 'sig'); |
$signed_list = $message->getArg(Auth_OpenID_OPENID_NS, 'signed'); | $signed_list = $message->getArg(Auth_OpenID_OPENID_NS, 'signed'); |
$signed_list = explode(",", $signed_list); | $signed_list = explode(",", $signed_list); |
$signed = $message; | $signed = $message; |
if ($signed->hasKey(Auth_OpenID_OPENID_NS, 'mode')) { | if ($signed->hasKey(Auth_OpenID_OPENID_NS, 'mode')) { |
$signed->setArg(Auth_OpenID_OPENID_NS, 'mode', 'id_res'); | $signed->setArg(Auth_OpenID_OPENID_NS, 'mode', 'id_res'); |
} | } |
$result = new Auth_OpenID_CheckAuthRequest($assoc_handle, $signed); | $result = new Auth_OpenID_CheckAuthRequest($assoc_handle, $signed); |
$result->message = $message; | $result->message = $message; |
$result->sig = $sig; | $result->sig = $sig; |
$result->invalidate_handle = $message->getArg(Auth_OpenID_OPENID_NS, | $result->invalidate_handle = $message->getArg(Auth_OpenID_OPENID_NS, |
'invalidate_handle'); | 'invalidate_handle'); |
return $result; | return $result; |
} | } |
function answer($signatory) | function answer($signatory) |
{ | { |
$is_valid = $signatory->verify($this->assoc_handle, $this->signed); | $is_valid = $signatory->verify($this->assoc_handle, $this->signed); |
// Now invalidate that assoc_handle so it this checkAuth | // Now invalidate that assoc_handle so it this checkAuth |
// message cannot be replayed. | // message cannot be replayed. |
$signatory->invalidate($this->assoc_handle, true); | $signatory->invalidate($this->assoc_handle, true); |
$response = new Auth_OpenID_ServerResponse($this); | $response = new Auth_OpenID_ServerResponse($this); |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'is_valid', | 'is_valid', |
($is_valid ? "true" : "false")); | ($is_valid ? "true" : "false")); |
if ($this->invalidate_handle) { | if ($this->invalidate_handle) { |
$assoc = $signatory->getAssociation($this->invalidate_handle, | $assoc = $signatory->getAssociation($this->invalidate_handle, |
false); | false); |
if (!$assoc) { | if (!$assoc) { |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'invalidate_handle', | 'invalidate_handle', |
$this->invalidate_handle); | $this->invalidate_handle); |
} | } |
} | } |
return $response; | return $response; |
} | } |
} | } |
/** | /** |
* A class implementing plaintext server sessions. | * A class implementing plaintext server sessions. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_PlainTextServerSession { | class Auth_OpenID_PlainTextServerSession { |
/** | /** |
* An object that knows how to handle association requests with no | * An object that knows how to handle association requests with no |
* session type. | * session type. |
*/ | */ |
var $session_type = 'no-encryption'; | var $session_type = 'no-encryption'; |
var $needs_math = false; | var $needs_math = false; |
var $allowed_assoc_types = array('HMAC-SHA1', 'HMAC-SHA256'); | var $allowed_assoc_types = array('HMAC-SHA1', 'HMAC-SHA256'); |
static function fromMessage($unused_request) | static function fromMessage($unused_request) |
{ | { |
return new Auth_OpenID_PlainTextServerSession(); | return new Auth_OpenID_PlainTextServerSession(); |
} | } |
function answer($secret) | function answer($secret) |
{ | { |
return array('mac_key' => base64_encode($secret)); | return array('mac_key' => base64_encode($secret)); |
} | } |
} | } |
/** | /** |
* A class implementing DH-SHA1 server sessions. | * A class implementing DH-SHA1 server sessions. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_DiffieHellmanSHA1ServerSession { | class Auth_OpenID_DiffieHellmanSHA1ServerSession { |
/** | /** |
* An object that knows how to handle association requests with | * An object that knows how to handle association requests with |
* the Diffie-Hellman session type. | * the Diffie-Hellman session type. |
*/ | */ |
var $session_type = 'DH-SHA1'; | var $session_type = 'DH-SHA1'; |
var $needs_math = true; | var $needs_math = true; |
var $allowed_assoc_types = array('HMAC-SHA1'); | var $allowed_assoc_types = array('HMAC-SHA1'); |
var $hash_func = 'Auth_OpenID_SHA1'; | var $hash_func = 'Auth_OpenID_SHA1'; |
function Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, $consumer_pubkey) | function Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, $consumer_pubkey) |
{ | { |
$this->dh = $dh; | $this->dh = $dh; |
$this->consumer_pubkey = $consumer_pubkey; | $this->consumer_pubkey = $consumer_pubkey; |
} | } |
static function getDH($message) | static function getDH($message) |
{ | { |
$dh_modulus = $message->getArg(Auth_OpenID_OPENID_NS, 'dh_modulus'); | $dh_modulus = $message->getArg(Auth_OpenID_OPENID_NS, 'dh_modulus'); |
$dh_gen = $message->getArg(Auth_OpenID_OPENID_NS, 'dh_gen'); | $dh_gen = $message->getArg(Auth_OpenID_OPENID_NS, 'dh_gen'); |
if ((($dh_modulus === null) && ($dh_gen !== null)) || | if ((($dh_modulus === null) && ($dh_gen !== null)) || |
(($dh_gen === null) && ($dh_modulus !== null))) { | (($dh_gen === null) && ($dh_modulus !== null))) { |
if ($dh_modulus === null) { | if ($dh_modulus === null) { |
$missing = 'modulus'; | $missing = 'modulus'; |
} else { | } else { |
$missing = 'generator'; | $missing = 'generator'; |
} | } |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
'If non-default modulus or generator is '. | 'If non-default modulus or generator is '. |
'supplied, both must be supplied. Missing '. | 'supplied, both must be supplied. Missing '. |
$missing); | $missing); |
} | } |
$lib = Auth_OpenID_getMathLib(); | $lib = Auth_OpenID_getMathLib(); |
if ($dh_modulus || $dh_gen) { | if ($dh_modulus || $dh_gen) { |
$dh_modulus = $lib->base64ToLong($dh_modulus); | $dh_modulus = $lib->base64ToLong($dh_modulus); |
$dh_gen = $lib->base64ToLong($dh_gen); | $dh_gen = $lib->base64ToLong($dh_gen); |
if ($lib->cmp($dh_modulus, 0) == 0 || | if ($lib->cmp($dh_modulus, 0) == 0 || |
$lib->cmp($dh_gen, 0) == 0) { | $lib->cmp($dh_gen, 0) == 0) { |
return new Auth_OpenID_ServerError( | return new Auth_OpenID_ServerError( |
$message, "Failed to parse dh_mod or dh_gen"); | $message, "Failed to parse dh_mod or dh_gen"); |
} | } |
$dh = new Auth_OpenID_DiffieHellman($dh_modulus, $dh_gen); | $dh = new Auth_OpenID_DiffieHellman($dh_modulus, $dh_gen); |
} else { | } else { |
$dh = new Auth_OpenID_DiffieHellman(); | $dh = new Auth_OpenID_DiffieHellman(); |
} | } |
$consumer_pubkey = $message->getArg(Auth_OpenID_OPENID_NS, | $consumer_pubkey = $message->getArg(Auth_OpenID_OPENID_NS, |
'dh_consumer_public'); | 'dh_consumer_public'); |
if ($consumer_pubkey === null) { | if ($consumer_pubkey === null) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
'Public key for DH-SHA1 session '. | 'Public key for DH-SHA1 session '. |
'not found in query'); | 'not found in query'); |
} | } |
$consumer_pubkey = | $consumer_pubkey = |
$lib->base64ToLong($consumer_pubkey); | $lib->base64ToLong($consumer_pubkey); |
if ($consumer_pubkey === false) { | if ($consumer_pubkey === false) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
"dh_consumer_public is not base64"); | "dh_consumer_public is not base64"); |
} | } |
return array($dh, $consumer_pubkey); | return array($dh, $consumer_pubkey); |
} | } |
static function fromMessage($message) | static function fromMessage($message) |
{ | { |
$result = Auth_OpenID_DiffieHellmanSHA1ServerSession::getDH($message); | $result = Auth_OpenID_DiffieHellmanSHA1ServerSession::getDH($message); |
if (is_a($result, 'Auth_OpenID_ServerError')) { | if (is_a($result, 'Auth_OpenID_ServerError')) { |
return $result; | return $result; |
} else { | } else { |
list($dh, $consumer_pubkey) = $result; | list($dh, $consumer_pubkey) = $result; |
return new Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, | return new Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, |
$consumer_pubkey); | $consumer_pubkey); |
} | } |
} | } |
function answer($secret) | function answer($secret) |
{ | { |
$lib = Auth_OpenID_getMathLib(); | $lib = Auth_OpenID_getMathLib(); |
$mac_key = $this->dh->xorSecret($this->consumer_pubkey, $secret, | $mac_key = $this->dh->xorSecret($this->consumer_pubkey, $secret, |
$this->hash_func); | $this->hash_func); |
return array( | return array( |
'dh_server_public' => | 'dh_server_public' => |
$lib->longToBase64($this->dh->public), | $lib->longToBase64($this->dh->public), |
'enc_mac_key' => base64_encode($mac_key)); | 'enc_mac_key' => base64_encode($mac_key)); |
} | } |
} | } |
/** | /** |
* A class implementing DH-SHA256 server sessions. | * A class implementing DH-SHA256 server sessions. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_DiffieHellmanSHA256ServerSession | class Auth_OpenID_DiffieHellmanSHA256ServerSession |
extends Auth_OpenID_DiffieHellmanSHA1ServerSession { | extends Auth_OpenID_DiffieHellmanSHA1ServerSession { |
var $session_type = 'DH-SHA256'; | var $session_type = 'DH-SHA256'; |
var $hash_func = 'Auth_OpenID_SHA256'; | var $hash_func = 'Auth_OpenID_SHA256'; |
var $allowed_assoc_types = array('HMAC-SHA256'); | var $allowed_assoc_types = array('HMAC-SHA256'); |
static function fromMessage($message) | static function fromMessage($message) |
{ | { |
$result = Auth_OpenID_DiffieHellmanSHA1ServerSession::getDH($message); | $result = Auth_OpenID_DiffieHellmanSHA1ServerSession::getDH($message); |
if (is_a($result, 'Auth_OpenID_ServerError')) { | if (is_a($result, 'Auth_OpenID_ServerError')) { |
return $result; | return $result; |
} else { | } else { |
list($dh, $consumer_pubkey) = $result; | list($dh, $consumer_pubkey) = $result; |
return new Auth_OpenID_DiffieHellmanSHA256ServerSession($dh, | return new Auth_OpenID_DiffieHellmanSHA256ServerSession($dh, |
$consumer_pubkey); | $consumer_pubkey); |
} | } |
} | } |
} | } |
/** | /** |
* A request to associate with the server. | * A request to associate with the server. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_AssociateRequest extends Auth_OpenID_Request { | class Auth_OpenID_AssociateRequest extends Auth_OpenID_Request { |
var $mode = "associate"; | var $mode = "associate"; |
static function getSessionClasses() | static function getSessionClasses() |
{ | { |
return array( | return array( |
'no-encryption' => 'Auth_OpenID_PlainTextServerSession', | 'no-encryption' => 'Auth_OpenID_PlainTextServerSession', |
'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ServerSession', | 'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ServerSession', |
'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ServerSession'); | 'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ServerSession'); |
} | } |
function Auth_OpenID_AssociateRequest($session, $assoc_type) | function Auth_OpenID_AssociateRequest($session, $assoc_type) |
{ | { |
$this->session = $session; | $this->session = $session; |
$this->namespace = Auth_OpenID_OPENID2_NS; | $this->namespace = Auth_OpenID_OPENID2_NS; |
$this->assoc_type = $assoc_type; | $this->assoc_type = $assoc_type; |
} | } |
static function fromMessage($message, $server=null) | static function fromMessage($message, $server=null) |
{ | { |
if ($message->isOpenID1()) { | if ($message->isOpenID1()) { |
$session_type = $message->getArg(Auth_OpenID_OPENID_NS, | $session_type = $message->getArg(Auth_OpenID_OPENID_NS, |
'session_type'); | 'session_type'); |
if ($session_type == 'no-encryption') { | if ($session_type == 'no-encryption') { |
// oidutil.log('Received OpenID 1 request with a no-encryption ' | // oidutil.log('Received OpenID 1 request with a no-encryption ' |
// 'assocaition session type. Continuing anyway.') | // 'assocaition session type. Continuing anyway.') |
} else if (!$session_type) { | } else if (!$session_type) { |
$session_type = 'no-encryption'; | $session_type = 'no-encryption'; |
} | } |
} else { | } else { |
$session_type = $message->getArg(Auth_OpenID_OPENID_NS, | $session_type = $message->getArg(Auth_OpenID_OPENID_NS, |
'session_type'); | 'session_type'); |
if ($session_type === null) { | if ($session_type === null) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
"session_type missing from request"); | "session_type missing from request"); |
} | } |
} | } |
$session_class = Auth_OpenID::arrayGet( | $session_class = Auth_OpenID::arrayGet( |
Auth_OpenID_AssociateRequest::getSessionClasses(), | Auth_OpenID_AssociateRequest::getSessionClasses(), |
$session_type); | $session_type); |
if ($session_class === null) { | if ($session_class === null) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
"Unknown session type " . | "Unknown session type " . |
$session_type); | $session_type); |
} | } |
$session = call_user_func(array($session_class, 'fromMessage'), | $session = call_user_func(array($session_class, 'fromMessage'), |
$message); | $message); |
if (is_a($session, 'Auth_OpenID_ServerError')) { | if (is_a($session, 'Auth_OpenID_ServerError')) { |
return $session; | return $session; |
} | } |
$assoc_type = $message->getArg(Auth_OpenID_OPENID_NS, | $assoc_type = $message->getArg(Auth_OpenID_OPENID_NS, |
'assoc_type', 'HMAC-SHA1'); | 'assoc_type', 'HMAC-SHA1'); |
if (!in_array($assoc_type, $session->allowed_assoc_types)) { | if (!in_array($assoc_type, $session->allowed_assoc_types)) { |
$fmt = "Session type %s does not support association type %s"; | $fmt = "Session type %s does not support association type %s"; |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
sprintf($fmt, $session_type, $assoc_type)); | sprintf($fmt, $session_type, $assoc_type)); |
} | } |
$obj = new Auth_OpenID_AssociateRequest($session, $assoc_type); | $obj = new Auth_OpenID_AssociateRequest($session, $assoc_type); |
$obj->message = $message; | $obj->message = $message; |
$obj->namespace = $message->getOpenIDNamespace(); | $obj->namespace = $message->getOpenIDNamespace(); |
return $obj; | return $obj; |
} | } |
function answer($assoc) | function answer($assoc) |
{ | { |
$response = new Auth_OpenID_ServerResponse($this); | $response = new Auth_OpenID_ServerResponse($this); |
$response->fields->updateArgs(Auth_OpenID_OPENID_NS, | $response->fields->updateArgs(Auth_OpenID_OPENID_NS, |
array( | array( |
'expires_in' => sprintf('%d', $assoc->getExpiresIn()), | 'expires_in' => sprintf('%d', $assoc->getExpiresIn()), |
'assoc_type' => $this->assoc_type, | 'assoc_type' => $this->assoc_type, |
'assoc_handle' => $assoc->handle)); | 'assoc_handle' => $assoc->handle)); |
$response->fields->updateArgs(Auth_OpenID_OPENID_NS, | $response->fields->updateArgs(Auth_OpenID_OPENID_NS, |
$this->session->answer($assoc->secret)); | $this->session->answer($assoc->secret)); |
if (! ($this->session->session_type == 'no-encryption' | if (! ($this->session->session_type == 'no-encryption' |
&& $this->message->isOpenID1())) { | && $this->message->isOpenID1())) { |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'session_type', | 'session_type', |
$this->session->session_type); | $this->session->session_type); |
} | } |
return $response; | return $response; |
} | } |
function answerUnsupported($text_message, | function answerUnsupported($text_message, |
$preferred_association_type=null, | $preferred_association_type=null, |
$preferred_session_type=null) | $preferred_session_type=null) |
{ | { |
if ($this->message->isOpenID1()) { | if ($this->message->isOpenID1()) { |
return new Auth_OpenID_ServerError($this->message); | return new Auth_OpenID_ServerError($this->message); |
} | } |
$response = new Auth_OpenID_ServerResponse($this); | $response = new Auth_OpenID_ServerResponse($this); |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'error_code', 'unsupported-type'); | 'error_code', 'unsupported-type'); |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'error', $text_message); | 'error', $text_message); |
if ($preferred_association_type) { | if ($preferred_association_type) { |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'assoc_type', | 'assoc_type', |
$preferred_association_type); | $preferred_association_type); |
} | } |
if ($preferred_session_type) { | if ($preferred_session_type) { |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'session_type', | 'session_type', |
$preferred_session_type); | $preferred_session_type); |
} | } |
$response->code = AUTH_OPENID_HTTP_ERROR; | $response->code = AUTH_OPENID_HTTP_ERROR; |
return $response; | return $response; |
} | } |
} | } |
/** | /** |
* A request to confirm the identity of a user. | * A request to confirm the identity of a user. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_CheckIDRequest extends Auth_OpenID_Request { | class Auth_OpenID_CheckIDRequest extends Auth_OpenID_Request { |
/** | /** |
* Return-to verification callback. Default is | * Return-to verification callback. Default is |
* Auth_OpenID_verifyReturnTo from TrustRoot.php. | * Auth_OpenID_verifyReturnTo from TrustRoot.php. |
*/ | */ |
var $verifyReturnTo = 'Auth_OpenID_verifyReturnTo'; | var $verifyReturnTo = 'Auth_OpenID_verifyReturnTo'; |
/** | /** |
* The mode of this request. | * The mode of this request. |
*/ | */ |
var $mode = "checkid_setup"; // or "checkid_immediate" | var $mode = "checkid_setup"; // or "checkid_immediate" |
/** | /** |
* Whether this request is for immediate mode. | * Whether this request is for immediate mode. |
*/ | */ |
var $immediate = false; | var $immediate = false; |
/** | /** |
* The trust_root value for this request. | * The trust_root value for this request. |
*/ | */ |
var $trust_root = null; | var $trust_root = null; |
/** | /** |
* The OpenID namespace for this request. | * The OpenID namespace for this request. |
* deprecated since version 2.0.2 | * deprecated since version 2.0.2 |
*/ | */ |
var $namespace; | var $namespace; |
static function make($message, $identity, $return_to, $trust_root = null, | static function make($message, $identity, $return_to, $trust_root = null, |
$immediate = false, $assoc_handle = null, $server = null) | $immediate = false, $assoc_handle = null, $server = null) |
{ | { |
if ($server === null) { | if ($server === null) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
"server must not be null"); | "server must not be null"); |
} | } |
if ($return_to && | if ($return_to && |
!Auth_OpenID_TrustRoot::_parse($return_to)) { | !Auth_OpenID_TrustRoot::_parse($return_to)) { |
return new Auth_OpenID_MalformedReturnURL($message, $return_to); | return new Auth_OpenID_MalformedReturnURL($message, $return_to); |
} | } |
$r = new Auth_OpenID_CheckIDRequest($identity, $return_to, | $r = new Auth_OpenID_CheckIDRequest($identity, $return_to, |
$trust_root, $immediate, | $trust_root, $immediate, |
$assoc_handle, $server); | $assoc_handle, $server); |
$r->namespace = $message->getOpenIDNamespace(); | $r->namespace = $message->getOpenIDNamespace(); |
$r->message = $message; | $r->message = $message; |
if (!$r->trustRootValid()) { | if (!$r->trustRootValid()) { |
return new Auth_OpenID_UntrustedReturnURL($message, | return new Auth_OpenID_UntrustedReturnURL($message, |
$return_to, | $return_to, |
$trust_root); | $trust_root); |
} else { | } else { |
return $r; | return $r; |
} | } |
} | } |
function Auth_OpenID_CheckIDRequest($identity, $return_to, | function Auth_OpenID_CheckIDRequest($identity, $return_to, |
$trust_root = null, $immediate = false, | $trust_root = null, $immediate = false, |
$assoc_handle = null, $server = null, | $assoc_handle = null, $server = null, |
$claimed_id = null) | $claimed_id = null) |
{ | { |
$this->namespace = Auth_OpenID_OPENID2_NS; | $this->namespace = Auth_OpenID_OPENID2_NS; |
$this->assoc_handle = $assoc_handle; | $this->assoc_handle = $assoc_handle; |
$this->identity = $identity; | $this->identity = $identity; |
if ($claimed_id === null) { | if ($claimed_id === null) { |
$this->claimed_id = $identity; | $this->claimed_id = $identity; |
} else { | } else { |
$this->claimed_id = $claimed_id; | $this->claimed_id = $claimed_id; |
} | } |
$this->return_to = $return_to; | $this->return_to = $return_to; |
$this->trust_root = $trust_root; | $this->trust_root = $trust_root; |
$this->server = $server; | $this->server = $server; |
if ($immediate) { | if ($immediate) { |
$this->immediate = true; | $this->immediate = true; |
$this->mode = "checkid_immediate"; | $this->mode = "checkid_immediate"; |
} else { | } else { |
$this->immediate = false; | $this->immediate = false; |
$this->mode = "checkid_setup"; | $this->mode = "checkid_setup"; |
} | } |
} | } |
function equals($other) | function equals($other) |
{ | { |
return ( | return ( |
(is_a($other, 'Auth_OpenID_CheckIDRequest')) && | (is_a($other, 'Auth_OpenID_CheckIDRequest')) && |
($this->namespace == $other->namespace) && | ($this->namespace == $other->namespace) && |
($this->assoc_handle == $other->assoc_handle) && | ($this->assoc_handle == $other->assoc_handle) && |
($this->identity == $other->identity) && | ($this->identity == $other->identity) && |
($this->claimed_id == $other->claimed_id) && | ($this->claimed_id == $other->claimed_id) && |
($this->return_to == $other->return_to) && | ($this->return_to == $other->return_to) && |
($this->trust_root == $other->trust_root)); | ($this->trust_root == $other->trust_root)); |
} | } |
/* | /* |
* Does the relying party publish the return_to URL for this | * Does the relying party publish the return_to URL for this |
* response under the realm? It is up to the provider to set a | * response under the realm? It is up to the provider to set a |
* policy for what kinds of realms should be allowed. This | * policy for what kinds of realms should be allowed. This |
* return_to URL verification reduces vulnerability to data-theft | * return_to URL verification reduces vulnerability to data-theft |
* attacks based on open proxies, corss-site-scripting, or open | * attacks based on open proxies, corss-site-scripting, or open |
* redirectors. | * redirectors. |
* | * |
* This check should only be performed after making sure that the | * This check should only be performed after making sure that the |
* return_to URL matches the realm. | * return_to URL matches the realm. |
* | * |
* @return true if the realm publishes a document with the | * @return true if the realm publishes a document with the |
* return_to URL listed, false if not or if discovery fails | * return_to URL listed, false if not or if discovery fails |
*/ | */ |
function returnToVerified() | function returnToVerified() |
{ | { |
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); | $fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); |
return call_user_func_array($this->verifyReturnTo, | return call_user_func_array($this->verifyReturnTo, |
array($this->trust_root, $this->return_to, $fetcher)); | array($this->trust_root, $this->return_to, $fetcher)); |
} | } |
static function fromMessage($message, $server) | static function fromMessage($message, $server) |
{ | { |
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode'); | $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode'); |
$immediate = null; | $immediate = null; |
if ($mode == "checkid_immediate") { | if ($mode == "checkid_immediate") { |
$immediate = true; | $immediate = true; |
$mode = "checkid_immediate"; | $mode = "checkid_immediate"; |
} else { | } else { |
$immediate = false; | $immediate = false; |
$mode = "checkid_setup"; | $mode = "checkid_setup"; |
} | } |
$return_to = $message->getArg(Auth_OpenID_OPENID_NS, | $return_to = $message->getArg(Auth_OpenID_OPENID_NS, |
'return_to'); | 'return_to'); |
if (($message->isOpenID1()) && | if (($message->isOpenID1()) && |
(!$return_to)) { | (!$return_to)) { |
$fmt = "Missing required field 'return_to' from checkid request"; | $fmt = "Missing required field 'return_to' from checkid request"; |
return new Auth_OpenID_ServerError($message, $fmt); | return new Auth_OpenID_ServerError($message, $fmt); |
} | } |
$identity = $message->getArg(Auth_OpenID_OPENID_NS, | $identity = $message->getArg(Auth_OpenID_OPENID_NS, |
'identity'); | 'identity'); |
$claimed_id = $message->getArg(Auth_OpenID_OPENID_NS, 'claimed_id'); | $claimed_id = $message->getArg(Auth_OpenID_OPENID_NS, 'claimed_id'); |
if ($message->isOpenID1()) { | if ($message->isOpenID1()) { |
if ($identity === null) { | if ($identity === null) { |
$s = "OpenID 1 message did not contain openid.identity"; | $s = "OpenID 1 message did not contain openid.identity"; |
return new Auth_OpenID_ServerError($message, $s); | return new Auth_OpenID_ServerError($message, $s); |
} | } |
} else { | } else { |
if ($identity && !$claimed_id) { | if ($identity && !$claimed_id) { |
$s = "OpenID 2.0 message contained openid.identity but not " . | $s = "OpenID 2.0 message contained openid.identity but not " . |
"claimed_id"; | "claimed_id"; |
return new Auth_OpenID_ServerError($message, $s); | return new Auth_OpenID_ServerError($message, $s); |
} else if ($claimed_id && !$identity) { | } else if ($claimed_id && !$identity) { |
$s = "OpenID 2.0 message contained openid.claimed_id " . | $s = "OpenID 2.0 message contained openid.claimed_id " . |
"but not identity"; | "but not identity"; |
return new Auth_OpenID_ServerError($message, $s); | return new Auth_OpenID_ServerError($message, $s); |
} | } |
} | } |
// There's a case for making self.trust_root be a TrustRoot | // There's a case for making self.trust_root be a TrustRoot |
// here. But if TrustRoot isn't currently part of the | // here. But if TrustRoot isn't currently part of the |
// "public" API, I'm not sure it's worth doing. | // "public" API, I'm not sure it's worth doing. |
if ($message->isOpenID1()) { | if ($message->isOpenID1()) { |
$trust_root_param = 'trust_root'; | $trust_root_param = 'trust_root'; |
} else { | } else { |
$trust_root_param = 'realm'; | $trust_root_param = 'realm'; |
} | } |
$trust_root = $message->getArg(Auth_OpenID_OPENID_NS, | $trust_root = $message->getArg(Auth_OpenID_OPENID_NS, |
$trust_root_param); | $trust_root_param); |
if (! $trust_root) { | if (! $trust_root) { |
$trust_root = $return_to; | $trust_root = $return_to; |
} | } |
if (! $message->isOpenID1() && | if (! $message->isOpenID1() && |
($return_to === null) && | ($return_to === null) && |
($trust_root === null)) { | ($trust_root === null)) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
"openid.realm required when openid.return_to absent"); | "openid.realm required when openid.return_to absent"); |
} | } |
$assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, | $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, |
'assoc_handle'); | 'assoc_handle'); |
$obj = Auth_OpenID_CheckIDRequest::make($message, | $obj = Auth_OpenID_CheckIDRequest::make($message, |
$identity, | $identity, |
$return_to, | $return_to, |
$trust_root, | $trust_root, |
$immediate, | $immediate, |
$assoc_handle, | $assoc_handle, |
$server); | $server); |
if (is_a($obj, 'Auth_OpenID_ServerError')) { | if (is_a($obj, 'Auth_OpenID_ServerError')) { |
return $obj; | return $obj; |
} | } |
$obj->claimed_id = $claimed_id; | $obj->claimed_id = $claimed_id; |
return $obj; | return $obj; |
} | } |
function idSelect() | function idSelect() |
{ | { |
// Is the identifier to be selected by the IDP? | // Is the identifier to be selected by the IDP? |
// So IDPs don't have to import the constant | // So IDPs don't have to import the constant |
return $this->identity == Auth_OpenID_IDENTIFIER_SELECT; | return $this->identity == Auth_OpenID_IDENTIFIER_SELECT; |
} | } |
function trustRootValid() | function trustRootValid() |
{ | { |
if (!$this->trust_root) { | if (!$this->trust_root) { |
return true; | return true; |
} | } |
$tr = Auth_OpenID_TrustRoot::_parse($this->trust_root); | $tr = Auth_OpenID_TrustRoot::_parse($this->trust_root); |
if ($tr === false) { | if ($tr === false) { |
return new Auth_OpenID_MalformedTrustRoot($this->message, | return new Auth_OpenID_MalformedTrustRoot($this->message, |
$this->trust_root); | $this->trust_root); |
} | } |
if ($this->return_to !== null) { | if ($this->return_to !== null) { |
return Auth_OpenID_TrustRoot::match($this->trust_root, | return Auth_OpenID_TrustRoot::match($this->trust_root, |
$this->return_to); | $this->return_to); |
} else { | } else { |
return true; | return true; |
} | } |
} | } |
/** | /** |
* Respond to this request. Return either an | * Respond to this request. Return either an |
* {@link Auth_OpenID_ServerResponse} or | * {@link Auth_OpenID_ServerResponse} or |
* {@link Auth_OpenID_ServerError}. | * {@link Auth_OpenID_ServerError}. |
* | * |
* @param bool $allow Allow this user to claim this identity, and | * @param bool $allow Allow this user to claim this identity, and |
* allow the consumer to have this information? | * allow the consumer to have this information? |
* | * |
* @param string $server_url DEPRECATED. Passing $op_endpoint to | * @param string $server_url DEPRECATED. Passing $op_endpoint to |
* the {@link Auth_OpenID_Server} constructor makes this optional. | * the {@link Auth_OpenID_Server} constructor makes this optional. |
* | * |
* When an OpenID 1.x immediate mode request does not succeed, it | * When an OpenID 1.x immediate mode request does not succeed, it |
* gets back a URL where the request may be carried out in a | * gets back a URL where the request may be carried out in a |
* not-so-immediate fashion. Pass my URL in here (the fully | * not-so-immediate fashion. Pass my URL in here (the fully |
* qualified address of this server's endpoint, i.e. | * qualified address of this server's endpoint, i.e. |
* http://example.com/server), and I will use it as a base for the | * http://example.com/server), and I will use it as a base for the |
* URL for a new request. | * URL for a new request. |
* | * |
* Optional for requests where {@link $immediate} is false or | * Optional for requests where {@link $immediate} is false or |
* $allow is true. | * $allow is true. |
* | * |
* @param string $identity The OP-local identifier to answer with. | * @param string $identity The OP-local identifier to answer with. |
* Only for use when the relying party requested identifier | * Only for use when the relying party requested identifier |
* selection. | * selection. |
* | * |
* @param string $claimed_id The claimed identifier to answer | * @param string $claimed_id The claimed identifier to answer |
* with, for use with identifier selection in the case where the | * with, for use with identifier selection in the case where the |
* claimed identifier and the OP-local identifier differ, | * claimed identifier and the OP-local identifier differ, |
* i.e. when the claimed_id uses delegation. | * i.e. when the claimed_id uses delegation. |
* | * |
* If $identity is provided but this is not, $claimed_id will | * If $identity is provided but this is not, $claimed_id will |
* default to the value of $identity. When answering requests | * default to the value of $identity. When answering requests |
* that did not ask for identifier selection, the response | * that did not ask for identifier selection, the response |
* $claimed_id will default to that of the request. | * $claimed_id will default to that of the request. |
* | * |
* This parameter is new in OpenID 2.0. | * This parameter is new in OpenID 2.0. |
* | * |
* @return mixed | * @return mixed |
*/ | */ |
function answer($allow, $server_url = null, $identity = null, | function answer($allow, $server_url = null, $identity = null, |
$claimed_id = null) | $claimed_id = null) |
{ | { |
if (!$this->return_to) { | if (!$this->return_to) { |
return new Auth_OpenID_NoReturnToError(); | return new Auth_OpenID_NoReturnToError(); |
} | } |
if (!$server_url) { | if (!$server_url) { |
if ((!$this->message->isOpenID1()) && | if ((!$this->message->isOpenID1()) && |
(!$this->server->op_endpoint)) { | (!$this->server->op_endpoint)) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"server should be constructed with op_endpoint to " . | "server should be constructed with op_endpoint to " . |
"respond to OpenID 2.0 messages."); | "respond to OpenID 2.0 messages."); |
} | } |
$server_url = $this->server->op_endpoint; | $server_url = $this->server->op_endpoint; |
} | } |
if ($allow) { | if ($allow) { |
$mode = 'id_res'; | $mode = 'id_res'; |
} else if ($this->message->isOpenID1()) { | } else if ($this->message->isOpenID1()) { |
if ($this->immediate) { | if ($this->immediate) { |
$mode = 'id_res'; | $mode = 'id_res'; |
} else { | } else { |
$mode = 'cancel'; | $mode = 'cancel'; |
} | } |
} else { | } else { |
if ($this->immediate) { | if ($this->immediate) { |
$mode = 'setup_needed'; | $mode = 'setup_needed'; |
} else { | } else { |
$mode = 'cancel'; | $mode = 'cancel'; |
} | } |
} | } |
if (!$this->trustRootValid()) { | if (!$this->trustRootValid()) { |
return new Auth_OpenID_UntrustedReturnURL(null, | return new Auth_OpenID_UntrustedReturnURL(null, |
$this->return_to, | $this->return_to, |
$this->trust_root); | $this->trust_root); |
} | } |
$response = new Auth_OpenID_ServerResponse($this); | $response = new Auth_OpenID_ServerResponse($this); |
if ($claimed_id && | if ($claimed_id && |
($this->message->isOpenID1())) { | ($this->message->isOpenID1())) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"claimed_id is new in OpenID 2.0 and not " . | "claimed_id is new in OpenID 2.0 and not " . |
"available for ".$this->namespace); | "available for ".$this->namespace); |
} | } |
if ($identity && !$claimed_id) { | if ($identity && !$claimed_id) { |
$claimed_id = $identity; | $claimed_id = $identity; |
} | } |
if ($allow) { | if ($allow) { |
if ($this->identity == Auth_OpenID_IDENTIFIER_SELECT) { | if ($this->identity == Auth_OpenID_IDENTIFIER_SELECT) { |
if (!$identity) { | if (!$identity) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"This request uses IdP-driven identifier selection. " . | "This request uses IdP-driven identifier selection. " . |
"You must supply an identifier in the response."); | "You must supply an identifier in the response."); |
} | } |
$response_identity = $identity; | $response_identity = $identity; |
$response_claimed_id = $claimed_id; | $response_claimed_id = $claimed_id; |
} else if ($this->identity) { | } else if ($this->identity) { |
if ($identity && | if ($identity && |
($this->identity != $identity)) { | ($this->identity != $identity)) { |
$fmt = "Request was for %s, cannot reply with identity %s"; | $fmt = "Request was for %s, cannot reply with identity %s"; |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
sprintf($fmt, $this->identity, $identity)); | sprintf($fmt, $this->identity, $identity)); |
} | } |
$response_identity = $this->identity; | $response_identity = $this->identity; |
$response_claimed_id = $this->claimed_id; | $response_claimed_id = $this->claimed_id; |
} else { | } else { |
if ($identity) { | if ($identity) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"This request specified no identity and " . | "This request specified no identity and " . |
"you supplied ".$identity); | "you supplied ".$identity); |
} | } |
$response_identity = null; | $response_identity = null; |
} | } |
if (($this->message->isOpenID1()) && | if (($this->message->isOpenID1()) && |
($response_identity === null)) { | ($response_identity === null)) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"Request was an OpenID 1 request, so response must " . | "Request was an OpenID 1 request, so response must " . |
"include an identifier."); | "include an identifier."); |
} | } |
$response->fields->updateArgs(Auth_OpenID_OPENID_NS, | $response->fields->updateArgs(Auth_OpenID_OPENID_NS, |
array('mode' => $mode, | array('mode' => $mode, |
'return_to' => $this->return_to, | 'return_to' => $this->return_to, |
'response_nonce' => Auth_OpenID_mkNonce())); | 'response_nonce' => Auth_OpenID_mkNonce())); |
if (!$this->message->isOpenID1()) { | if (!$this->message->isOpenID1()) { |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'op_endpoint', $server_url); | 'op_endpoint', $server_url); |
} | } |
if ($response_identity !== null) { | if ($response_identity !== null) { |
$response->fields->setArg( | $response->fields->setArg( |
Auth_OpenID_OPENID_NS, | Auth_OpenID_OPENID_NS, |
'identity', | 'identity', |
$response_identity); | $response_identity); |
if ($this->message->isOpenID2()) { | if ($this->message->isOpenID2()) { |
$response->fields->setArg( | $response->fields->setArg( |
Auth_OpenID_OPENID_NS, | Auth_OpenID_OPENID_NS, |
'claimed_id', | 'claimed_id', |
$response_claimed_id); | $response_claimed_id); |
} | } |
} | } |
} else { | } else { |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'mode', $mode); | 'mode', $mode); |
if ($this->immediate) { | if ($this->immediate) { |
if (($this->message->isOpenID1()) && | if (($this->message->isOpenID1()) && |
(!$server_url)) { | (!$server_url)) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
'setup_url is required for $allow=false \ | 'setup_url is required for $allow=false \ |
in OpenID 1.x immediate mode.'); | in OpenID 1.x immediate mode.'); |
} | } |
$setup_request = new Auth_OpenID_CheckIDRequest( | $setup_request = new Auth_OpenID_CheckIDRequest( |
$this->identity, | $this->identity, |
$this->return_to, | $this->return_to, |
$this->trust_root, | $this->trust_root, |
false, | false, |
$this->assoc_handle, | $this->assoc_handle, |
$this->server, | $this->server, |
$this->claimed_id); | $this->claimed_id); |
$setup_request->message = $this->message; | $setup_request->message = $this->message; |
$setup_url = $setup_request->encodeToURL($server_url); | $setup_url = $setup_request->encodeToURL($server_url); |
if ($setup_url === null) { | if ($setup_url === null) { |
return new Auth_OpenID_NoReturnToError(); | return new Auth_OpenID_NoReturnToError(); |
} | } |
$response->fields->setArg(Auth_OpenID_OPENID_NS, | $response->fields->setArg(Auth_OpenID_OPENID_NS, |
'user_setup_url', | 'user_setup_url', |
$setup_url); | $setup_url); |
} | } |
} | } |
return $response; | return $response; |
} | } |
function encodeToURL($server_url) | function encodeToURL($server_url) |
{ | { |
if (!$this->return_to) { | if (!$this->return_to) { |
return new Auth_OpenID_NoReturnToError(); | return new Auth_OpenID_NoReturnToError(); |
} | } |
// Imported from the alternate reality where these classes are | // Imported from the alternate reality where these classes are |
// used in both the client and server code, so Requests are | // used in both the client and server code, so Requests are |
// Encodable too. That's right, code imported from alternate | // Encodable too. That's right, code imported from alternate |
// realities all for the love of you, id_res/user_setup_url. | // realities all for the love of you, id_res/user_setup_url. |
$q = array('mode' => $this->mode, | $q = array('mode' => $this->mode, |
'identity' => $this->identity, | 'identity' => $this->identity, |
'claimed_id' => $this->claimed_id, | 'claimed_id' => $this->claimed_id, |
'return_to' => $this->return_to); | 'return_to' => $this->return_to); |
if ($this->trust_root) { | if ($this->trust_root) { |
if ($this->message->isOpenID1()) { | if ($this->message->isOpenID1()) { |
$q['trust_root'] = $this->trust_root; | $q['trust_root'] = $this->trust_root; |
} else { | } else { |
$q['realm'] = $this->trust_root; | $q['realm'] = $this->trust_root; |
} | } |
} | } |
if ($this->assoc_handle) { | if ($this->assoc_handle) { |
$q['assoc_handle'] = $this->assoc_handle; | $q['assoc_handle'] = $this->assoc_handle; |
} | } |
$response = new Auth_OpenID_Message( | $response = new Auth_OpenID_Message( |
$this->message->getOpenIDNamespace()); | $this->message->getOpenIDNamespace()); |
$response->updateArgs(Auth_OpenID_OPENID_NS, $q); | $response->updateArgs(Auth_OpenID_OPENID_NS, $q); |
return $response->toURL($server_url); | return $response->toURL($server_url); |
} | } |
function getCancelURL() | function getCancelURL() |
{ | { |
if (!$this->return_to) { | if (!$this->return_to) { |
return new Auth_OpenID_NoReturnToError(); | return new Auth_OpenID_NoReturnToError(); |
} | } |
if ($this->immediate) { | if ($this->immediate) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"Cancel is not an appropriate \ | "Cancel is not an appropriate \ |
response to immediate mode \ | response to immediate mode \ |
requests."); | requests."); |
} | } |
$response = new Auth_OpenID_Message( | $response = new Auth_OpenID_Message( |
$this->message->getOpenIDNamespace()); | $this->message->getOpenIDNamespace()); |
$response->setArg(Auth_OpenID_OPENID_NS, 'mode', 'cancel'); | $response->setArg(Auth_OpenID_OPENID_NS, 'mode', 'cancel'); |
return $response->toURL($this->return_to); | return $response->toURL($this->return_to); |
} | } |
} | } |
/** | /** |
* This class encapsulates the response to an OpenID server request. | * This class encapsulates the response to an OpenID server request. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_ServerResponse { | class Auth_OpenID_ServerResponse { |
function Auth_OpenID_ServerResponse($request) | function Auth_OpenID_ServerResponse($request) |
{ | { |
$this->request = $request; | $this->request = $request; |
$this->fields = new Auth_OpenID_Message($this->request->namespace); | $this->fields = new Auth_OpenID_Message($this->request->namespace); |
} | } |
function whichEncoding() | function whichEncoding() |
{ | { |
global $_Auth_OpenID_Request_Modes; | global $_Auth_OpenID_Request_Modes; |
if (in_array($this->request->mode, $_Auth_OpenID_Request_Modes)) { | if (in_array($this->request->mode, $_Auth_OpenID_Request_Modes)) { |
if ($this->fields->isOpenID2() && | if ($this->fields->isOpenID2() && |
(strlen($this->encodeToURL()) > | (strlen($this->encodeToURL()) > |
Auth_OpenID_OPENID1_URL_LIMIT)) { | Auth_OpenID_OPENID1_URL_LIMIT)) { |
return Auth_OpenID_ENCODE_HTML_FORM; | return Auth_OpenID_ENCODE_HTML_FORM; |
} else { | } else { |
return Auth_OpenID_ENCODE_URL; | return Auth_OpenID_ENCODE_URL; |
} | } |
} else { | } else { |
return Auth_OpenID_ENCODE_KVFORM; | return Auth_OpenID_ENCODE_KVFORM; |
} | } |
} | } |
/* | /* |
* Returns the form markup for this response. | * Returns the form markup for this response. |
* | * |
* @return str | * @return str |
*/ | */ |
function toFormMarkup($form_tag_attrs=null) | function toFormMarkup($form_tag_attrs=null) |
{ | { |
return $this->fields->toFormMarkup($this->request->return_to, | return $this->fields->toFormMarkup($this->request->return_to, |
$form_tag_attrs); | $form_tag_attrs); |
} | } |
/* | /* |
* Returns an HTML document containing the form markup for this | * Returns an HTML document containing the form markup for this |
* response that autosubmits with javascript. | * response that autosubmits with javascript. |
*/ | */ |
function toHTML() | function toHTML() |
{ | { |
return Auth_OpenID::autoSubmitHTML($this->toFormMarkup()); | return Auth_OpenID::autoSubmitHTML($this->toFormMarkup()); |
} | } |
/* | /* |
* Returns True if this response's encoding is ENCODE_HTML_FORM. | * Returns True if this response's encoding is ENCODE_HTML_FORM. |
* Convenience method for server authors. | * Convenience method for server authors. |
* | * |
* @return bool | * @return bool |
*/ | */ |
function renderAsForm() | function renderAsForm() |
{ | { |
return $this->whichEncoding() == Auth_OpenID_ENCODE_HTML_FORM; | return $this->whichEncoding() == Auth_OpenID_ENCODE_HTML_FORM; |
} | } |
function encodeToURL() | function encodeToURL() |
{ | { |
return $this->fields->toURL($this->request->return_to); | return $this->fields->toURL($this->request->return_to); |
} | } |
function addExtension($extension_response) | function addExtension($extension_response) |
{ | { |
$extension_response->toMessage($this->fields); | $extension_response->toMessage($this->fields); |
} | } |
function needsSigning() | function needsSigning() |
{ | { |
return $this->fields->getArg(Auth_OpenID_OPENID_NS, | return $this->fields->getArg(Auth_OpenID_OPENID_NS, |
'mode') == 'id_res'; | 'mode') == 'id_res'; |
} | } |
function encodeToKVForm() | function encodeToKVForm() |
{ | { |
return $this->fields->toKVForm(); | return $this->fields->toKVForm(); |
} | } |
} | } |
/** | /** |
* A web-capable response object which you can use to generate a | * A web-capable response object which you can use to generate a |
* user-agent response. | * user-agent response. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_WebResponse { | class Auth_OpenID_WebResponse { |
var $code = AUTH_OPENID_HTTP_OK; | var $code = AUTH_OPENID_HTTP_OK; |
var $body = ""; | var $body = ""; |
function Auth_OpenID_WebResponse($code = null, $headers = null, | function Auth_OpenID_WebResponse($code = null, $headers = null, |
$body = null) | $body = null) |
{ | { |
if ($code) { | if ($code) { |
$this->code = $code; | $this->code = $code; |
} | } |
if ($headers !== null) { | if ($headers !== null) { |
$this->headers = $headers; | $this->headers = $headers; |
} else { | } else { |
$this->headers = array(); | $this->headers = array(); |
} | } |
if ($body !== null) { | if ($body !== null) { |
$this->body = $body; | $this->body = $body; |
} | } |
} | } |
} | } |
/** | /** |
* Responsible for the signature of query data and the verification of | * Responsible for the signature of query data and the verification of |
* OpenID signature values. | * OpenID signature values. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_Signatory { | class Auth_OpenID_Signatory { |
// = 14 * 24 * 60 * 60; # 14 days, in seconds | // = 14 * 24 * 60 * 60; # 14 days, in seconds |
var $SECRET_LIFETIME = 1209600; | var $SECRET_LIFETIME = 1209600; |
// keys have a bogus server URL in them because the filestore | // keys have a bogus server URL in them because the filestore |
// really does expect that key to be a URL. This seems a little | // really does expect that key to be a URL. This seems a little |
// silly for the server store, since I expect there to be only one | // silly for the server store, since I expect there to be only one |
// server URL. | // server URL. |
var $normal_key = 'http://localhost/|normal'; | var $normal_key = 'http://localhost/|normal'; |
var $dumb_key = 'http://localhost/|dumb'; | var $dumb_key = 'http://localhost/|dumb'; |
/** | /** |
* Create a new signatory using a given store. | * Create a new signatory using a given store. |
*/ | */ |
function Auth_OpenID_Signatory($store) | function Auth_OpenID_Signatory($store) |
{ | { |
// assert store is not None | // assert store is not None |
$this->store = $store; | $this->store = $store; |
} | } |
/** | /** |
* Verify, using a given association handle, a signature with | * Verify, using a given association handle, a signature with |
* signed key-value pairs from an HTTP request. | * signed key-value pairs from an HTTP request. |
*/ | */ |
function verify($assoc_handle, $message) | function verify($assoc_handle, $message) |
{ | { |
$assoc = $this->getAssociation($assoc_handle, true); | $assoc = $this->getAssociation($assoc_handle, true); |
if (!$assoc) { | if (!$assoc) { |
// oidutil.log("failed to get assoc with handle %r to verify sig %r" | // oidutil.log("failed to get assoc with handle %r to verify sig %r" |
// % (assoc_handle, sig)) | // % (assoc_handle, sig)) |
return false; | return false; |
} | } |
return $assoc->checkMessageSignature($message); | return $assoc->checkMessageSignature($message); |
} | } |
/** | /** |
* Given a response, sign the fields in the response's 'signed' | * Given a response, sign the fields in the response's 'signed' |
* list, and insert the signature into the response. | * list, and insert the signature into the response. |
*/ | */ |
function sign($response) | function sign($response) |
{ | { |
$signed_response = $response; | $signed_response = $response; |
$assoc_handle = $response->request->assoc_handle; | $assoc_handle = $response->request->assoc_handle; |
if ($assoc_handle) { | if ($assoc_handle) { |
// normal mode | // normal mode |
$assoc = $this->getAssociation($assoc_handle, false, false); | $assoc = $this->getAssociation($assoc_handle, false, false); |
if (!$assoc || ($assoc->getExpiresIn() <= 0)) { | if (!$assoc || ($assoc->getExpiresIn() <= 0)) { |
// fall back to dumb mode | // fall back to dumb mode |
$signed_response->fields->setArg(Auth_OpenID_OPENID_NS, | $signed_response->fields->setArg(Auth_OpenID_OPENID_NS, |
'invalidate_handle', $assoc_handle); | 'invalidate_handle', $assoc_handle); |
$assoc_type = ($assoc ? $assoc->assoc_type : 'HMAC-SHA1'); | $assoc_type = ($assoc ? $assoc->assoc_type : 'HMAC-SHA1'); |
if ($assoc && ($assoc->getExpiresIn() <= 0)) { | if ($assoc && ($assoc->getExpiresIn() <= 0)) { |
$this->invalidate($assoc_handle, false); | $this->invalidate($assoc_handle, false); |
} | } |
$assoc = $this->createAssociation(true, $assoc_type); | $assoc = $this->createAssociation(true, $assoc_type); |
} | } |
} else { | } else { |
// dumb mode. | // dumb mode. |
$assoc = $this->createAssociation(true); | $assoc = $this->createAssociation(true); |
} | } |
$signed_response->fields = $assoc->signMessage( | $signed_response->fields = $assoc->signMessage( |
$signed_response->fields); | $signed_response->fields); |
return $signed_response; | return $signed_response; |
} | } |
/** | /** |
* Make a new association. | * Make a new association. |
*/ | */ |
function createAssociation($dumb = true, $assoc_type = 'HMAC-SHA1') | function createAssociation($dumb = true, $assoc_type = 'HMAC-SHA1') |
{ | { |
$secret = Auth_OpenID_CryptUtil::getBytes( | $secret = Auth_OpenID_CryptUtil::getBytes( |
Auth_OpenID_getSecretSize($assoc_type)); | Auth_OpenID_getSecretSize($assoc_type)); |
$uniq = base64_encode(Auth_OpenID_CryptUtil::getBytes(4)); | $uniq = base64_encode(Auth_OpenID_CryptUtil::getBytes(4)); |
$handle = sprintf('{%s}{%x}{%s}', $assoc_type, intval(time()), $uniq); | $handle = sprintf('{%s}{%x}{%s}', $assoc_type, intval(time()), $uniq); |
$assoc = Auth_OpenID_Association::fromExpiresIn( | $assoc = Auth_OpenID_Association::fromExpiresIn( |
$this->SECRET_LIFETIME, $handle, $secret, $assoc_type); | $this->SECRET_LIFETIME, $handle, $secret, $assoc_type); |
if ($dumb) { | if ($dumb) { |
$key = $this->dumb_key; | $key = $this->dumb_key; |
} else { | } else { |
$key = $this->normal_key; | $key = $this->normal_key; |
} | } |
$this->store->storeAssociation($key, $assoc); | $this->store->storeAssociation($key, $assoc); |
return $assoc; | return $assoc; |
} | } |
/** | /** |
* Given an association handle, get the association from the | * Given an association handle, get the association from the |
* store, or return a ServerError or null if something goes wrong. | * store, or return a ServerError or null if something goes wrong. |
*/ | */ |
function getAssociation($assoc_handle, $dumb, $check_expiration=true) | function getAssociation($assoc_handle, $dumb, $check_expiration=true) |
{ | { |
if ($assoc_handle === null) { | if ($assoc_handle === null) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"assoc_handle must not be null"); | "assoc_handle must not be null"); |
} | } |
if ($dumb) { | if ($dumb) { |
$key = $this->dumb_key; | $key = $this->dumb_key; |
} else { | } else { |
$key = $this->normal_key; | $key = $this->normal_key; |
} | } |
$assoc = $this->store->getAssociation($key, $assoc_handle); | $assoc = $this->store->getAssociation($key, $assoc_handle); |
if (($assoc !== null) && ($assoc->getExpiresIn() <= 0)) { | if (($assoc !== null) && ($assoc->getExpiresIn() <= 0)) { |
if ($check_expiration) { | if ($check_expiration) { |
$this->store->removeAssociation($key, $assoc_handle); | $this->store->removeAssociation($key, $assoc_handle); |
$assoc = null; | $assoc = null; |
} | } |
} | } |
return $assoc; | return $assoc; |
} | } |
/** | /** |
* Invalidate a given association handle. | * Invalidate a given association handle. |
*/ | */ |
function invalidate($assoc_handle, $dumb) | function invalidate($assoc_handle, $dumb) |
{ | { |
if ($dumb) { | if ($dumb) { |
$key = $this->dumb_key; | $key = $this->dumb_key; |
} else { | } else { |
$key = $this->normal_key; | $key = $this->normal_key; |
} | } |
$this->store->removeAssociation($key, $assoc_handle); | $this->store->removeAssociation($key, $assoc_handle); |
} | } |
} | } |
/** | /** |
* Encode an {@link Auth_OpenID_ServerResponse} to an | * Encode an {@link Auth_OpenID_ServerResponse} to an |
* {@link Auth_OpenID_WebResponse}. | * {@link Auth_OpenID_WebResponse}. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_Encoder { | class Auth_OpenID_Encoder { |
var $responseFactory = 'Auth_OpenID_WebResponse'; | var $responseFactory = 'Auth_OpenID_WebResponse'; |
/** | /** |
* Encode an {@link Auth_OpenID_ServerResponse} and return an | * Encode an {@link Auth_OpenID_ServerResponse} and return an |
* {@link Auth_OpenID_WebResponse}. | * {@link Auth_OpenID_WebResponse}. |
*/ | */ |
function encode($response) | function encode($response) |
{ | { |
$cls = $this->responseFactory; | $cls = $this->responseFactory; |
$encode_as = $response->whichEncoding(); | $encode_as = $response->whichEncoding(); |
if ($encode_as == Auth_OpenID_ENCODE_KVFORM) { | if ($encode_as == Auth_OpenID_ENCODE_KVFORM) { |
$wr = new $cls(null, null, $response->encodeToKVForm()); | $wr = new $cls(null, null, $response->encodeToKVForm()); |
if (is_a($response, 'Auth_OpenID_ServerError')) { | if (is_a($response, 'Auth_OpenID_ServerError')) { |
$wr->code = AUTH_OPENID_HTTP_ERROR; | $wr->code = AUTH_OPENID_HTTP_ERROR; |
} | } |
} else if ($encode_as == Auth_OpenID_ENCODE_URL) { | } else if ($encode_as == Auth_OpenID_ENCODE_URL) { |
$location = $response->encodeToURL(); | $location = $response->encodeToURL(); |
$wr = new $cls(AUTH_OPENID_HTTP_REDIRECT, | $wr = new $cls(AUTH_OPENID_HTTP_REDIRECT, |
array('location' => $location)); | array('location' => $location)); |
} else if ($encode_as == Auth_OpenID_ENCODE_HTML_FORM) { | } else if ($encode_as == Auth_OpenID_ENCODE_HTML_FORM) { |
$wr = new $cls(AUTH_OPENID_HTTP_OK, array(), | $wr = new $cls(AUTH_OPENID_HTTP_OK, array(), |
$response->toHTML()); | $response->toHTML()); |
} else { | } else { |
return new Auth_OpenID_EncodingError($response); | return new Auth_OpenID_EncodingError($response); |
} | } |
/* Allow the response to carry a custom error code (ex: for Association errors) */ | /* Allow the response to carry a custom error code (ex: for Association errors) */ |
if(isset($response->code)) { | if(isset($response->code)) { |
$wr->code = $response->code; | $wr->code = $response->code; |
} | } |
return $wr; | return $wr; |
} | } |
} | } |
/** | /** |
* An encoder which also takes care of signing fields when required. | * An encoder which also takes care of signing fields when required. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_SigningEncoder extends Auth_OpenID_Encoder { | class Auth_OpenID_SigningEncoder extends Auth_OpenID_Encoder { |
function Auth_OpenID_SigningEncoder($signatory) | function Auth_OpenID_SigningEncoder($signatory) |
{ | { |
$this->signatory = $signatory; | $this->signatory = $signatory; |
} | } |
/** | /** |
* Sign an {@link Auth_OpenID_ServerResponse} and return an | * Sign an {@link Auth_OpenID_ServerResponse} and return an |
* {@link Auth_OpenID_WebResponse}. | * {@link Auth_OpenID_WebResponse}. |
*/ | */ |
function encode($response) | function encode($response) |
{ | { |
// the isinstance is a bit of a kludge... it means there isn't | // the isinstance is a bit of a kludge... it means there isn't |
// really an adapter to make the interfaces quite match. | // really an adapter to make the interfaces quite match. |
if (!is_a($response, 'Auth_OpenID_ServerError') && | if (!is_a($response, 'Auth_OpenID_ServerError') && |
$response->needsSigning()) { | $response->needsSigning()) { |
if (!$this->signatory) { | if (!$this->signatory) { |
return new Auth_OpenID_ServerError(null, | return new Auth_OpenID_ServerError(null, |
"Must have a store to sign request"); | "Must have a store to sign request"); |
} | } |
if ($response->fields->hasKey(Auth_OpenID_OPENID_NS, 'sig')) { | if ($response->fields->hasKey(Auth_OpenID_OPENID_NS, 'sig')) { |
return new Auth_OpenID_AlreadySigned($response); | return new Auth_OpenID_AlreadySigned($response); |
} | } |
$response = $this->signatory->sign($response); | $response = $this->signatory->sign($response); |
} | } |
return parent::encode($response); | return parent::encode($response); |
} | } |
} | } |
/** | /** |
* Decode an incoming query into an Auth_OpenID_Request. | * Decode an incoming query into an Auth_OpenID_Request. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_Decoder { | class Auth_OpenID_Decoder { |
function Auth_OpenID_Decoder($server) | function Auth_OpenID_Decoder($server) |
{ | { |
$this->server = $server; | $this->server = $server; |
$this->handlers = array( | $this->handlers = array( |
'checkid_setup' => 'Auth_OpenID_CheckIDRequest', | 'checkid_setup' => 'Auth_OpenID_CheckIDRequest', |
'checkid_immediate' => 'Auth_OpenID_CheckIDRequest', | 'checkid_immediate' => 'Auth_OpenID_CheckIDRequest', |
'check_authentication' => 'Auth_OpenID_CheckAuthRequest', | 'check_authentication' => 'Auth_OpenID_CheckAuthRequest', |
'associate' => 'Auth_OpenID_AssociateRequest' | 'associate' => 'Auth_OpenID_AssociateRequest' |
); | ); |
} | } |
/** | /** |
* Given an HTTP query in an array (key-value pairs), decode it | * Given an HTTP query in an array (key-value pairs), decode it |
* into an Auth_OpenID_Request object. | * into an Auth_OpenID_Request object. |
*/ | */ |
function decode($query) | function decode($query) |
{ | { |
if (!$query) { | if (!$query) { |
return null; | return null; |
} | } |
$message = Auth_OpenID_Message::fromPostArgs($query); | $message = Auth_OpenID_Message::fromPostArgs($query); |
if ($message === null) { | if ($message === null) { |
/* | /* |
* It's useful to have a Message attached to a | * It's useful to have a Message attached to a |
* ProtocolError, so we override the bad ns value to build | * ProtocolError, so we override the bad ns value to build |
* a Message out of it. Kinda kludgy, since it's made of | * a Message out of it. Kinda kludgy, since it's made of |
* lies, but the parts that aren't lies are more useful | * lies, but the parts that aren't lies are more useful |
* than a 'None'. | * than a 'None'. |
*/ | */ |
$old_ns = $query['openid.ns']; | $old_ns = $query['openid.ns']; |
$query['openid.ns'] = Auth_OpenID_OPENID2_NS; | $query['openid.ns'] = Auth_OpenID_OPENID2_NS; |
$message = Auth_OpenID_Message::fromPostArgs($query); | $message = Auth_OpenID_Message::fromPostArgs($query); |
return new Auth_OpenID_ServerError( | return new Auth_OpenID_ServerError( |
$message, | $message, |
sprintf("Invalid OpenID namespace URI: %s", $old_ns)); | sprintf("Invalid OpenID namespace URI: %s", $old_ns)); |
} | } |
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode'); | $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode'); |
if (!$mode) { | if (!$mode) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
"No mode value in message"); | "No mode value in message"); |
} | } |
if (Auth_OpenID::isFailure($mode)) { | if (Auth_OpenID::isFailure($mode)) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
$mode->message); | $mode->message); |
} | } |
$handlerCls = Auth_OpenID::arrayGet($this->handlers, $mode, | $handlerCls = Auth_OpenID::arrayGet($this->handlers, $mode, |
$this->defaultDecoder($message)); | $this->defaultDecoder($message)); |
if (!is_a($handlerCls, 'Auth_OpenID_ServerError')) { | if (!is_a($handlerCls, 'Auth_OpenID_ServerError')) { |
return call_user_func_array(array($handlerCls, 'fromMessage'), | return call_user_func_array(array($handlerCls, 'fromMessage'), |
array($message, $this->server)); | array($message, $this->server)); |
} else { | } else { |
return $handlerCls; | return $handlerCls; |
} | } |
} | } |
function defaultDecoder($message) | function defaultDecoder($message) |
{ | { |
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode'); | $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode'); |
if (Auth_OpenID::isFailure($mode)) { | if (Auth_OpenID::isFailure($mode)) { |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
$mode->message); | $mode->message); |
} | } |
return new Auth_OpenID_ServerError($message, | return new Auth_OpenID_ServerError($message, |
sprintf("Unrecognized OpenID mode %s", $mode)); | sprintf("Unrecognized OpenID mode %s", $mode)); |
} | } |
} | } |
/** | /** |
* An error that indicates an encoding problem occurred. | * An error that indicates an encoding problem occurred. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_EncodingError { | class Auth_OpenID_EncodingError { |
function Auth_OpenID_EncodingError($response) | function Auth_OpenID_EncodingError($response) |
{ | { |
$this->response = $response; | $this->response = $response; |
} | } |
} | } |
/** | /** |
* An error that indicates that a response was already signed. | * An error that indicates that a response was already signed. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_AlreadySigned extends Auth_OpenID_EncodingError { | class Auth_OpenID_AlreadySigned extends Auth_OpenID_EncodingError { |
// This response is already signed. | // This response is already signed. |
} | } |
/** | /** |
* An error that indicates that the given return_to is not under the | * An error that indicates that the given return_to is not under the |
* given trust_root. | * given trust_root. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_UntrustedReturnURL extends Auth_OpenID_ServerError { | class Auth_OpenID_UntrustedReturnURL extends Auth_OpenID_ServerError { |
function Auth_OpenID_UntrustedReturnURL($message, $return_to, | function Auth_OpenID_UntrustedReturnURL($message, $return_to, |
$trust_root) | $trust_root) |
{ | { |
parent::Auth_OpenID_ServerError($message, "Untrusted return_to URL"); | parent::Auth_OpenID_ServerError($message, "Untrusted return_to URL"); |
$this->return_to = $return_to; | $this->return_to = $return_to; |
$this->trust_root = $trust_root; | $this->trust_root = $trust_root; |
} | } |
function toString() | function toString() |
{ | { |
return sprintf("return_to %s not under trust_root %s", | return sprintf("return_to %s not under trust_root %s", |
$this->return_to, $this->trust_root); | $this->return_to, $this->trust_root); |
} | } |
} | } |
/** | /** |
* I handle requests for an OpenID server. | * I handle requests for an OpenID server. |
* | * |
* Some types of requests (those which are not checkid requests) may | * Some types of requests (those which are not checkid requests) may |
* be handed to my {@link handleRequest} method, and I will take care | * be handed to my {@link handleRequest} method, and I will take care |
* of it and return a response. | * of it and return a response. |
* | * |
* For your convenience, I also provide an interface to {@link | * For your convenience, I also provide an interface to {@link |
* Auth_OpenID_Decoder::decode()} and {@link | * Auth_OpenID_Decoder::decode()} and {@link |
* Auth_OpenID_SigningEncoder::encode()} through my methods {@link | * Auth_OpenID_SigningEncoder::encode()} through my methods {@link |
* decodeRequest} and {@link encodeResponse}. | * decodeRequest} and {@link encodeResponse}. |
* | * |
* All my state is encapsulated in an {@link Auth_OpenID_OpenIDStore}. | * All my state is encapsulated in an {@link Auth_OpenID_OpenIDStore}. |
* | * |
* Example: | * Example: |
* | * |
* <pre> $oserver = new Auth_OpenID_Server(Auth_OpenID_FileStore($data_path), | * <pre> $oserver = new Auth_OpenID_Server(Auth_OpenID_FileStore($data_path), |
* "http://example.com/op"); | * "http://example.com/op"); |
* $request = $oserver->decodeRequest(); | * $request = $oserver->decodeRequest(); |
* if (in_array($request->mode, array('checkid_immediate', | * if (in_array($request->mode, array('checkid_immediate', |
* 'checkid_setup'))) { | * 'checkid_setup'))) { |
* if ($app->isAuthorized($request->identity, $request->trust_root)) { | * if ($app->isAuthorized($request->identity, $request->trust_root)) { |
* $response = $request->answer(true); | * $response = $request->answer(true); |
* } else if ($request->immediate) { | * } else if ($request->immediate) { |
* $response = $request->answer(false); | * $response = $request->answer(false); |
* } else { | * } else { |
* $app->showDecidePage($request); | * $app->showDecidePage($request); |
* return; | * return; |
* } | * } |
* } else { | * } else { |
* $response = $oserver->handleRequest($request); | * $response = $oserver->handleRequest($request); |
* } | * } |
* | * |
* $webresponse = $oserver->encode($response);</pre> | * $webresponse = $oserver->encode($response);</pre> |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_Server { | class Auth_OpenID_Server { |
function Auth_OpenID_Server($store, $op_endpoint=null) | function Auth_OpenID_Server($store, $op_endpoint=null) |
{ | { |
$this->store = $store; | $this->store = $store; |
$this->signatory = new Auth_OpenID_Signatory($this->store); | $this->signatory = new Auth_OpenID_Signatory($this->store); |
$this->encoder = new Auth_OpenID_SigningEncoder($this->signatory); | $this->encoder = new Auth_OpenID_SigningEncoder($this->signatory); |
$this->decoder = new Auth_OpenID_Decoder($this); | $this->decoder = new Auth_OpenID_Decoder($this); |
$this->op_endpoint = $op_endpoint; | $this->op_endpoint = $op_endpoint; |
$this->negotiator = Auth_OpenID_getDefaultNegotiator(); | $this->negotiator = Auth_OpenID_getDefaultNegotiator(); |
} | } |
/** | /** |
* Handle a request. Given an {@link Auth_OpenID_Request} object, | * Handle a request. Given an {@link Auth_OpenID_Request} object, |
* call the appropriate {@link Auth_OpenID_Server} method to | * call the appropriate {@link Auth_OpenID_Server} method to |
* process the request and generate a response. | * process the request and generate a response. |
* | * |
* @param Auth_OpenID_Request $request An {@link Auth_OpenID_Request} | * @param Auth_OpenID_Request $request An {@link Auth_OpenID_Request} |
* returned by {@link Auth_OpenID_Server::decodeRequest()}. | * returned by {@link Auth_OpenID_Server::decodeRequest()}. |
* | * |
* @return Auth_OpenID_ServerResponse $response A response object | * @return Auth_OpenID_ServerResponse $response A response object |
* capable of generating a user-agent reply. | * capable of generating a user-agent reply. |
*/ | */ |
function handleRequest($request) | function handleRequest($request) |
{ | { |
if (method_exists($this, "openid_" . $request->mode)) { | if (method_exists($this, "openid_" . $request->mode)) { |
$handler = array($this, "openid_" . $request->mode); | $handler = array($this, "openid_" . $request->mode); |
return call_user_func($handler, &$request); | return call_user_func($handler, $request); |
} | } |
return null; | return null; |
} | } |
/** | /** |
* The callback for 'check_authentication' messages. | * The callback for 'check_authentication' messages. |
*/ | */ |
function openid_check_authentication($request) | function openid_check_authentication($request) |
{ | { |
return $request->answer($this->signatory); | return $request->answer($this->signatory); |
} | } |
/** | /** |
* The callback for 'associate' messages. | * The callback for 'associate' messages. |
*/ | */ |
function openid_associate($request) | function openid_associate($request) |
{ | { |
$assoc_type = $request->assoc_type; | $assoc_type = $request->assoc_type; |
$session_type = $request->session->session_type; | $session_type = $request->session->session_type; |
if ($this->negotiator->isAllowed($assoc_type, $session_type)) { | if ($this->negotiator->isAllowed($assoc_type, $session_type)) { |
$assoc = $this->signatory->createAssociation(false, | $assoc = $this->signatory->createAssociation(false, |
$assoc_type); | $assoc_type); |
return $request->answer($assoc); | return $request->answer($assoc); |
} else { | } else { |
$message = sprintf('Association type %s is not supported with '. | $message = sprintf('Association type %s is not supported with '. |
'session type %s', $assoc_type, $session_type); | 'session type %s', $assoc_type, $session_type); |
list($preferred_assoc_type, $preferred_session_type) = | list($preferred_assoc_type, $preferred_session_type) = |
$this->negotiator->getAllowedType(); | $this->negotiator->getAllowedType(); |
return $request->answerUnsupported($message, | return $request->answerUnsupported($message, |
$preferred_assoc_type, | $preferred_assoc_type, |
$preferred_session_type); | $preferred_session_type); |
} | } |
} | } |
/** | /** |
* Encodes as response in the appropriate format suitable for | * Encodes as response in the appropriate format suitable for |
* sending to the user agent. | * sending to the user agent. |
*/ | */ |
function encodeResponse($response) | function encodeResponse($response) |
{ | { |
return $this->encoder->encode($response); | return $this->encoder->encode($response); |
} | } |
/** | /** |
* Decodes a query args array into the appropriate | * Decodes a query args array into the appropriate |
* {@link Auth_OpenID_Request} object. | * {@link Auth_OpenID_Request} object. |
*/ | */ |
function decodeRequest($query=null) | function decodeRequest($query=null) |
{ | { |
if ($query === null) { | if ($query === null) { |
$query = Auth_OpenID::getQuery(); | $query = Auth_OpenID::getQuery(); |
} | } |
return $this->decoder->decode($query); | return $this->decoder->decode($query); |
} | } |
} | } |
<?php | |
/** | |
* OpenID Server Request | |
* | |
* @see Auth_OpenID_Server | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Imports | |
*/ | |
require_once "Auth/OpenID.php"; | |
/** | |
* Object that holds the state of a request to the OpenID server | |
* | |
* With accessor functions to get at the internal request data. | |
* | |
* @see Auth_OpenID_Server | |
* @package OpenID | |
*/ | |
class Auth_OpenID_ServerRequest { | |
function Auth_OpenID_ServerRequest() | |
{ | |
$this->mode = null; | |
} | |
} | |
<?php | <?php |
/** | /** |
* Functions for dealing with OpenID trust roots | * Functions for dealing with OpenID trust roots |
* | * |
* PHP versions 4 and 5 | * PHP versions 4 and 5 |
* | * |
* LICENSE: See the COPYING file included in this distribution. | * LICENSE: See the COPYING file included in this distribution. |
* | * |
* @package OpenID | * @package OpenID |
* @author JanRain, Inc. <openid@janrain.com> | * @author JanRain, Inc. <openid@janrain.com> |
* @copyright 2005-2008 Janrain, Inc. | * @copyright 2005-2008 Janrain, Inc. |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache |
*/ | */ |
require_once 'Auth/OpenID/Discover.php'; | require_once 'Auth/OpenID/Discover.php'; |
/** | /** |
* A regular expression that matches a domain ending in a top-level domains. | * A regular expression that matches a domain ending in a top-level domains. |
* Used in checking trust roots for sanity. | * Used in checking trust roots for sanity. |
* | * |
* @access private | * @access private |
*/ | */ |
define('Auth_OpenID___TLDs', | define('Auth_OpenID___TLDs', |
'/\.(ac|ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|asia' . | '/\.(ac|ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|arpa|as|asia' . |
'|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br' . | '|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bm|bn|bo|br' . |
'|bs|bt|bv|bw|by|bz|ca|cat|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co' . | '|bs|bt|bv|bw|by|bz|ca|cat|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co' . |
'|com|coop|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg' . | '|com|coop|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|edu|ee|eg' . |
'|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl' . | '|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl' . |
'|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie' . | '|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie' . |
'|il|im|in|info|int|io|iq|ir|is|it|je|jm|jo|jobs|jp|ke|kg|kh' . | '|il|im|in|info|int|io|iq|ir|is|it|je|jm|jo|jobs|jp|ke|kg|kh' . |
'|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly' . | '|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly' . |
'|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mo|mobi|mp|mq|mr|ms|mt' . | '|ma|mc|md|me|mg|mh|mil|mk|ml|mm|mn|mo|mobi|mp|mq|mr|ms|mt' . |
'|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no' . | '|mu|museum|mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no' . |
'|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt' . | '|np|nr|nu|nz|om|org|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pro|ps|pt' . |
'|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl' . | '|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl' . |
'|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm' . | '|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tel|tf|tg|th|tj|tk|tl|tm' . |
'|tn|to|tp|tr|travel|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve' . | '|tn|to|tp|tr|travel|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve' . |
'|vg|vi|vn|vu|wf|ws|xn--0zwm56d|xn--11b5bs3a9aj6g' . | '|vg|vi|vn|vu|wf|ws|xn--0zwm56d|xn--11b5bs3a9aj6g' . |
'|xn--80akhbyknj4f|xn--9t4b11yi5a|xn--deba0ad|xn--g6w251d' . | '|xn--80akhbyknj4f|xn--9t4b11yi5a|xn--deba0ad|xn--g6w251d' . |
'|xn--hgbk6aj7f53bba|xn--hlcj6aya9esc7a|xn--jxalpdlp' . | '|xn--hgbk6aj7f53bba|xn--hlcj6aya9esc7a|xn--jxalpdlp' . |
'|xn--kgbechtv|xn--zckzah|ye|yt|yu|za|zm|zw)\.?$/'); | '|xn--kgbechtv|xn--zckzah|ye|yt|yu|za|zm|zw)\.?$/'); |
define('Auth_OpenID___HostSegmentRe', | define('Auth_OpenID___HostSegmentRe', |
"/^(?:[-a-zA-Z0-9!$&'\\(\\)\\*+,;=._~]|%[a-zA-Z0-9]{2})*$/"); | "/^(?:[-a-zA-Z0-9!$&'\\(\\)\\*+,;=._~]|%[a-zA-Z0-9]{2})*$/"); |
/** | /** |
* A wrapper for trust-root related functions | * A wrapper for trust-root related functions |
*/ | */ |
class Auth_OpenID_TrustRoot { | class Auth_OpenID_TrustRoot { |
/* | /* |
* Return a discovery URL for this realm. | * Return a discovery URL for this realm. |
* | * |
* Return null if the realm could not be parsed or was not valid. | * Return null if the realm could not be parsed or was not valid. |
* | * |
* @param return_to The relying party return URL of the OpenID | * @param return_to The relying party return URL of the OpenID |
* authentication request | * authentication request |
* | * |
* @return The URL upon which relying party discovery should be | * @return The URL upon which relying party discovery should be |
* run in order to verify the return_to URL | * run in order to verify the return_to URL |
*/ | */ |
static function buildDiscoveryURL($realm) | static function buildDiscoveryURL($realm) |
{ | { |
$parsed = Auth_OpenID_TrustRoot::_parse($realm); | $parsed = Auth_OpenID_TrustRoot::_parse($realm); |
if ($parsed === false) { | if ($parsed === false) { |
return false; | return false; |
} | } |
if ($parsed['wildcard']) { | if ($parsed['wildcard']) { |
// Use "www." in place of the star | // Use "www." in place of the star |
if ($parsed['host'][0] != '.') { | if ($parsed['host'][0] != '.') { |
return false; | return false; |
} | } |
$www_domain = 'www' . $parsed['host']; | $www_domain = 'www' . $parsed['host']; |
return sprintf('%s://%s%s', $parsed['scheme'], | return sprintf('%s://%s%s', $parsed['scheme'], |
$www_domain, $parsed['path']); | $www_domain, $parsed['path']); |
} else { | } else { |
return $parsed['unparsed']; | return $parsed['unparsed']; |
} | } |
} | } |
/** | /** |
* Parse a URL into its trust_root parts. | * Parse a URL into its trust_root parts. |
* | * |
* @static | * @static |
* | * |
* @access private | * @access private |
* | * |
* @param string $trust_root The url to parse | * @param string $trust_root The url to parse |
* | * |
* @return mixed $parsed Either an associative array of trust root | * @return mixed $parsed Either an associative array of trust root |
* parts or false if parsing failed. | * parts or false if parsing failed. |
*/ | */ |
static function _parse($trust_root) | static function _parse($trust_root) |
{ | { |
$trust_root = Auth_OpenID_urinorm($trust_root); | $trust_root = Auth_OpenID_urinorm($trust_root); |
if ($trust_root === null) { | if ($trust_root === null) { |
return false; | return false; |
} | } |
if (preg_match("/:\/\/[^:]+(:\d+){2,}(\/|$)/", $trust_root)) { | if (preg_match("/:\/\/[^:]+(:\d+){2,}(\/|$)/", $trust_root)) { |
return false; | return false; |
} | } |
$parts = @parse_url($trust_root); | $parts = @parse_url($trust_root); |
if ($parts === false) { | if ($parts === false) { |
return false; | return false; |
} | } |
$required_parts = array('scheme', 'host'); | $required_parts = array('scheme', 'host'); |
$forbidden_parts = array('user', 'pass', 'fragment'); | $forbidden_parts = array('user', 'pass', 'fragment'); |
$keys = array_keys($parts); | $keys = array_keys($parts); |
if (array_intersect($keys, $required_parts) != $required_parts) { | if (array_intersect($keys, $required_parts) != $required_parts) { |
return false; | return false; |
} | } |
if (array_intersect($keys, $forbidden_parts) != array()) { | if (array_intersect($keys, $forbidden_parts) != array()) { |
return false; | return false; |
} | } |
if (!preg_match(Auth_OpenID___HostSegmentRe, $parts['host'])) { | if (!preg_match(Auth_OpenID___HostSegmentRe, $parts['host'])) { |
return false; | return false; |
} | } |
$scheme = strtolower($parts['scheme']); | $scheme = strtolower($parts['scheme']); |
$allowed_schemes = array('http', 'https'); | $allowed_schemes = array('http', 'https'); |
if (!in_array($scheme, $allowed_schemes)) { | if (!in_array($scheme, $allowed_schemes)) { |
return false; | return false; |
} | } |
$parts['scheme'] = $scheme; | $parts['scheme'] = $scheme; |
$host = strtolower($parts['host']); | $host = strtolower($parts['host']); |
$hostparts = explode('*', $host); | $hostparts = explode('*', $host); |
switch (count($hostparts)) { | switch (count($hostparts)) { |
case 1: | case 1: |
$parts['wildcard'] = false; | $parts['wildcard'] = false; |
break; | break; |
case 2: | case 2: |
if ($hostparts[0] || | if ($hostparts[0] || |
($hostparts[1] && substr($hostparts[1], 0, 1) != '.')) { | ($hostparts[1] && substr($hostparts[1], 0, 1) != '.')) { |
return false; | return false; |
} | } |
$host = $hostparts[1]; | $host = $hostparts[1]; |
$parts['wildcard'] = true; | $parts['wildcard'] = true; |
break; | break; |
default: | default: |
return false; | return false; |
} | } |
if (strpos($host, ':') !== false) { | if (strpos($host, ':') !== false) { |
return false; | return false; |
} | } |
$parts['host'] = $host; | $parts['host'] = $host; |
if (isset($parts['path'])) { | if (isset($parts['path'])) { |
$path = strtolower($parts['path']); | $path = strtolower($parts['path']); |
if (substr($path, 0, 1) != '/') { | if (substr($path, 0, 1) != '/') { |
return false; | return false; |
} | } |
} else { | } else { |
$path = '/'; | $path = '/'; |
} | } |
$parts['path'] = $path; | $parts['path'] = $path; |
if (!isset($parts['port'])) { | if (!isset($parts['port'])) { |
$parts['port'] = false; | $parts['port'] = false; |
} | } |
$parts['unparsed'] = $trust_root; | $parts['unparsed'] = $trust_root; |
return $parts; | return $parts; |
} | } |
/** | /** |
* Is this trust root sane? | * Is this trust root sane? |
* | * |
* A trust root is sane if it is syntactically valid and it has a | * A trust root is sane if it is syntactically valid and it has a |
* reasonable domain name. Specifically, the domain name must be | * reasonable domain name. Specifically, the domain name must be |
* more than one level below a standard TLD or more than two | * more than one level below a standard TLD or more than two |
* levels below a two-letter tld. | * levels below a two-letter tld. |
* | * |
* For example, '*.com' is not a sane trust root, but '*.foo.com' | * For example, '*.com' is not a sane trust root, but '*.foo.com' |
* is. '*.co.uk' is not sane, but '*.bbc.co.uk' is. | * is. '*.co.uk' is not sane, but '*.bbc.co.uk' is. |
* | * |
* This check is not always correct, but it attempts to err on the | * This check is not always correct, but it attempts to err on the |
* side of marking sane trust roots insane instead of marking | * side of marking sane trust roots insane instead of marking |
* insane trust roots sane. For example, 'kink.fm' is marked as | * insane trust roots sane. For example, 'kink.fm' is marked as |
* insane even though it "should" (for some meaning of should) be | * insane even though it "should" (for some meaning of should) be |
* marked sane. | * marked sane. |
* | * |
* This function should be used when creating OpenID servers to | * This function should be used when creating OpenID servers to |
* alert the users of the server when a consumer attempts to get | * alert the users of the server when a consumer attempts to get |
* the user to accept a suspicious trust root. | * the user to accept a suspicious trust root. |
* | * |
* @static | * @static |
* @param string $trust_root The trust root to check | * @param string $trust_root The trust root to check |
* @return bool $sanity Whether the trust root looks OK | * @return bool $sanity Whether the trust root looks OK |
*/ | */ |
static function isSane($trust_root) | static function isSane($trust_root) |
{ | { |
$parts = Auth_OpenID_TrustRoot::_parse($trust_root); | $parts = Auth_OpenID_TrustRoot::_parse($trust_root); |
if ($parts === false) { | if ($parts === false) { |
return false; | return false; |
} | } |
// Localhost is a special case | // Localhost is a special case |
if ($parts['host'] == 'localhost') { | if ($parts['host'] == 'localhost') { |
return true; | return true; |
} | } |
$host_parts = explode('.', $parts['host']); | $host_parts = explode('.', $parts['host']); |
if ($parts['wildcard']) { | if ($parts['wildcard']) { |
// Remove the empty string from the beginning of the array | // Remove the empty string from the beginning of the array |
array_shift($host_parts); | array_shift($host_parts); |
} | } |
if ($host_parts && !$host_parts[count($host_parts) - 1]) { | if ($host_parts && !$host_parts[count($host_parts) - 1]) { |
array_pop($host_parts); | array_pop($host_parts); |
} | } |
if (!$host_parts) { | if (!$host_parts) { |
return false; | return false; |
} | } |
// Don't allow adjacent dots | // Don't allow adjacent dots |
if (in_array('', $host_parts, true)) { | if (in_array('', $host_parts, true)) { |
return false; | return false; |
} | } |
// Get the top-level domain of the host. If it is not a valid TLD, | // Get the top-level domain of the host. If it is not a valid TLD, |
// it's not sane. | // it's not sane. |
preg_match(Auth_OpenID___TLDs, $parts['host'], $matches); | preg_match(Auth_OpenID___TLDs, $parts['host'], $matches); |
if (!$matches) { | if (!$matches) { |
return false; | return false; |
} | } |
$tld = $matches[1]; | $tld = $matches[1]; |
if (count($host_parts) == 1) { | if (count($host_parts) == 1) { |
return false; | return false; |
} | } |
if ($parts['wildcard']) { | if ($parts['wildcard']) { |
// It's a 2-letter tld with a short second to last segment | // It's a 2-letter tld with a short second to last segment |
// so there needs to be more than two segments specified | // so there needs to be more than two segments specified |
// (e.g. *.co.uk is insane) | // (e.g. *.co.uk is insane) |
$second_level = $host_parts[count($host_parts) - 2]; | $second_level = $host_parts[count($host_parts) - 2]; |
if (strlen($tld) == 2 && strlen($second_level) <= 3) { | if (strlen($tld) == 2 && strlen($second_level) <= 3) { |
return count($host_parts) > 2; | return count($host_parts) > 2; |
} | } |
} | } |
return true; | return true; |
} | } |
/** | /** |
* Does this URL match the given trust root? | * Does this URL match the given trust root? |
* | * |
* Return whether the URL falls under the given trust root. This | * Return whether the URL falls under the given trust root. This |
* does not check whether the trust root is sane. If the URL or | * does not check whether the trust root is sane. If the URL or |
* trust root do not parse, this function will return false. | * trust root do not parse, this function will return false. |
* | * |
* @param string $trust_root The trust root to match against | * @param string $trust_root The trust root to match against |
* | * |
* @param string $url The URL to check | * @param string $url The URL to check |
* | * |
* @return bool $matches Whether the URL matches against the | * @return bool $matches Whether the URL matches against the |
* trust root | * trust root |
*/ | */ |
static function match($trust_root, $url) | static function match($trust_root, $url) |
{ | { |
$trust_root_parsed = Auth_OpenID_TrustRoot::_parse($trust_root); | $trust_root_parsed = Auth_OpenID_TrustRoot::_parse($trust_root); |
$url_parsed = Auth_OpenID_TrustRoot::_parse($url); | $url_parsed = Auth_OpenID_TrustRoot::_parse($url); |
if (!$trust_root_parsed || !$url_parsed) { | if (!$trust_root_parsed || !$url_parsed) { |
return false; | return false; |
} | } |
// Check hosts matching | // Check hosts matching |
if ($url_parsed['wildcard']) { | if ($url_parsed['wildcard']) { |
return false; | return false; |
} | } |
if ($trust_root_parsed['wildcard']) { | if ($trust_root_parsed['wildcard']) { |
$host_tail = $trust_root_parsed['host']; | $host_tail = $trust_root_parsed['host']; |
$host = $url_parsed['host']; | $host = $url_parsed['host']; |
if ($host_tail && | if ($host_tail && |
substr($host, -(strlen($host_tail))) != $host_tail && | substr($host, -(strlen($host_tail))) != $host_tail && |
substr($host_tail, 1) != $host) { | substr($host_tail, 1) != $host) { |
return false; | return false; |
} | } |
} else { | } else { |
if ($trust_root_parsed['host'] != $url_parsed['host']) { | if ($trust_root_parsed['host'] != $url_parsed['host']) { |
return false; | return false; |
} | } |
} | } |
// Check path and query matching | // Check path and query matching |
$base_path = $trust_root_parsed['path']; | $base_path = $trust_root_parsed['path']; |
$path = $url_parsed['path']; | $path = $url_parsed['path']; |
if (!isset($trust_root_parsed['query'])) { | if (!isset($trust_root_parsed['query'])) { |
if ($base_path != $path) { | if ($base_path != $path) { |
if (substr($path, 0, strlen($base_path)) != $base_path) { | if (substr($path, 0, strlen($base_path)) != $base_path) { |
return false; | return false; |
} | } |
if (substr($base_path, strlen($base_path) - 1, 1) != '/' && | if (substr($base_path, strlen($base_path) - 1, 1) != '/' && |
substr($path, strlen($base_path), 1) != '/') { | substr($path, strlen($base_path), 1) != '/') { |
return false; | return false; |
} | } |
} | } |
} else { | } else { |
$base_query = $trust_root_parsed['query']; | $base_query = $trust_root_parsed['query']; |
$query = @$url_parsed['query']; | $query = @$url_parsed['query']; |
$qplus = substr($query, 0, strlen($base_query) + 1); | $qplus = substr($query, 0, strlen($base_query) + 1); |
$bqplus = $base_query . '&'; | $bqplus = $base_query . '&'; |
if ($base_path != $path || | if ($base_path != $path || |
($base_query != $query && $qplus != $bqplus)) { | ($base_query != $query && $qplus != $bqplus)) { |
return false; | return false; |
} | } |
} | } |
// The port and scheme need to match exactly | // The port and scheme need to match exactly |
return ($trust_root_parsed['scheme'] == $url_parsed['scheme'] && | return ($trust_root_parsed['scheme'] == $url_parsed['scheme'] && |
$url_parsed['port'] === $trust_root_parsed['port']); | $url_parsed['port'] === $trust_root_parsed['port']); |
} | } |
} | } |
/* | /* |
* If the endpoint is a relying party OpenID return_to endpoint, | * If the endpoint is a relying party OpenID return_to endpoint, |
* return the endpoint URL. Otherwise, return None. | * return the endpoint URL. Otherwise, return None. |
* | * |
* This function is intended to be used as a filter for the Yadis | * This function is intended to be used as a filter for the Yadis |
* filtering interface. | * filtering interface. |
* | * |
* @see: C{L{openid.yadis.services}} | * @see: C{L{openid.yadis.services}} |
* @see: C{L{openid.yadis.filters}} | * @see: C{L{openid.yadis.filters}} |
* | * |
* @param endpoint: An XRDS BasicServiceEndpoint, as returned by | * @param endpoint: An XRDS BasicServiceEndpoint, as returned by |
* performing Yadis dicovery. | * performing Yadis dicovery. |
* | * |
* @returns: The endpoint URL or None if the endpoint is not a | * @returns: The endpoint URL or None if the endpoint is not a |
* relying party endpoint. | * relying party endpoint. |
*/ | */ |
function filter_extractReturnURL($endpoint) | function filter_extractReturnURL($endpoint) |
{ | { |
if ($endpoint->matchTypes(array(Auth_OpenID_RP_RETURN_TO_URL_TYPE))) { | if ($endpoint->matchTypes(array(Auth_OpenID_RP_RETURN_TO_URL_TYPE))) { |
return $endpoint; | return $endpoint; |
} else { | } else { |
return null; | return null; |
} | } |
} | } |
function &Auth_OpenID_extractReturnURL(&$endpoint_list) | function &Auth_OpenID_extractReturnURL(&$endpoint_list) |
{ | { |
$result = array(); | $result = array(); |
foreach ($endpoint_list as $endpoint) { | foreach ($endpoint_list as $endpoint) { |
if (filter_extractReturnURL($endpoint)) { | if (filter_extractReturnURL($endpoint)) { |
$result[] = $endpoint; | $result[] = $endpoint; |
} | } |
} | } |
return $result; | return $result; |
} | } |
/* | /* |
* Is the return_to URL under one of the supplied allowed return_to | * Is the return_to URL under one of the supplied allowed return_to |
* URLs? | * URLs? |
*/ | */ |
function Auth_OpenID_returnToMatches($allowed_return_to_urls, $return_to) | function Auth_OpenID_returnToMatches($allowed_return_to_urls, $return_to) |
{ | { |
foreach ($allowed_return_to_urls as $allowed_return_to) { | foreach ($allowed_return_to_urls as $allowed_return_to) { |
// A return_to pattern works the same as a realm, except that | // A return_to pattern works the same as a realm, except that |
// it's not allowed to use a wildcard. We'll model this by | // it's not allowed to use a wildcard. We'll model this by |
// parsing it as a realm, and not trying to match it if it has | // parsing it as a realm, and not trying to match it if it has |
// a wildcard. | // a wildcard. |
$return_realm = Auth_OpenID_TrustRoot::_parse($allowed_return_to); | $return_realm = Auth_OpenID_TrustRoot::_parse($allowed_return_to); |
if (// Parses as a trust root | if (// Parses as a trust root |
($return_realm !== false) && | ($return_realm !== false) && |
// Does not have a wildcard | // Does not have a wildcard |
(!$return_realm['wildcard']) && | (!$return_realm['wildcard']) && |
// Matches the return_to that we passed in with it | // Matches the return_to that we passed in with it |
(Auth_OpenID_TrustRoot::match($allowed_return_to, $return_to))) { | (Auth_OpenID_TrustRoot::match($allowed_return_to, $return_to))) { |
return true; | return true; |
} | } |
} | } |
// No URL in the list matched | // No URL in the list matched |
return false; | return false; |
} | } |
/* | /* |
* Given a relying party discovery URL return a list of return_to | * Given a relying party discovery URL return a list of return_to |
* URLs. | * URLs. |
*/ | */ |
function Auth_OpenID_getAllowedReturnURLs($relying_party_url, $fetcher, | function Auth_OpenID_getAllowedReturnURLs($relying_party_url, $fetcher, |
$discover_function=null) | $discover_function=null) |
{ | { |
if ($discover_function === null) { | if ($discover_function === null) { |
$discover_function = array('Auth_Yadis_Yadis', 'discover'); | $discover_function = array('Auth_Yadis_Yadis', 'discover'); |
} | } |
$xrds_parse_cb = array('Auth_OpenID_ServiceEndpoint', 'consumerFromXRDS'); | $xrds_parse_cb = array('Auth_OpenID_ServiceEndpoint', 'consumerFromXRDS'); |
list($rp_url_after_redirects, $endpoints) = | list($rp_url_after_redirects, $endpoints) = |
Auth_Yadis_getServiceEndpoints($relying_party_url, $xrds_parse_cb, | Auth_Yadis_getServiceEndpoints($relying_party_url, $xrds_parse_cb, |
$discover_function, $fetcher); | $discover_function, $fetcher); |
if ($rp_url_after_redirects != $relying_party_url) { | if ($rp_url_after_redirects != $relying_party_url) { |
// Verification caused a redirect | // Verification caused a redirect |
return false; | return false; |
} | } |
call_user_func_array($discover_function, | call_user_func_array($discover_function, |
array($relying_party_url, &$fetcher)); | array($relying_party_url, $fetcher)); |
$return_to_urls = array(); | $return_to_urls = array(); |
$matching_endpoints = Auth_OpenID_extractReturnURL($endpoints); | $matching_endpoints = Auth_OpenID_extractReturnURL($endpoints); |
foreach ($matching_endpoints as $e) { | foreach ($matching_endpoints as $e) { |
$return_to_urls[] = $e->server_url; | $return_to_urls[] = $e->server_url; |
} | } |
return $return_to_urls; | return $return_to_urls; |
} | } |
/* | /* |
* Verify that a return_to URL is valid for the given realm. | * Verify that a return_to URL is valid for the given realm. |
* | * |
* This function builds a discovery URL, performs Yadis discovery on | * This function builds a discovery URL, performs Yadis discovery on |
* it, makes sure that the URL does not redirect, parses out the | * it, makes sure that the URL does not redirect, parses out the |
* return_to URLs, and finally checks to see if the current return_to | * return_to URLs, and finally checks to see if the current return_to |
* URL matches the return_to. | * URL matches the return_to. |
* | * |
* @return true if the return_to URL is valid for the realm | * @return true if the return_to URL is valid for the realm |
*/ | */ |
function Auth_OpenID_verifyReturnTo($realm_str, $return_to, $fetcher, | function Auth_OpenID_verifyReturnTo($realm_str, $return_to, $fetcher, |
$_vrfy='Auth_OpenID_getAllowedReturnURLs') | $_vrfy='Auth_OpenID_getAllowedReturnURLs') |
{ | { |
$disco_url = Auth_OpenID_TrustRoot::buildDiscoveryURL($realm_str); | $disco_url = Auth_OpenID_TrustRoot::buildDiscoveryURL($realm_str); |
if ($disco_url === false) { | if ($disco_url === false) { |
return false; | return false; |
} | } |
$allowable_urls = call_user_func_array($_vrfy, | $allowable_urls = call_user_func_array($_vrfy, |
array($disco_url, $fetcher)); | array($disco_url, $fetcher)); |
// The realm_str could not be parsed. | // The realm_str could not be parsed. |
if ($allowable_urls === false) { | if ($allowable_urls === false) { |
return false; | return false; |
} | } |
if (Auth_OpenID_returnToMatches($allowable_urls, $return_to)) { | if (Auth_OpenID_returnToMatches($allowable_urls, $return_to)) { |
return true; | return true; |
} else { | } else { |
return false; | return false; |
} | } |
} | } |
<?php | |
/** | |
* URI normalization routines. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
require_once 'Auth/Yadis/Misc.php'; | |
// from appendix B of rfc 3986 (http://www.ietf.org/rfc/rfc3986.txt) | |
function Auth_OpenID_getURIPattern() | |
{ | |
return '&^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?&'; | |
} | |
function Auth_OpenID_getAuthorityPattern() | |
{ | |
return '/^([^@]*@)?([^:]*)(:.*)?/'; | |
} | |
function Auth_OpenID_getEncodedPattern() | |
{ | |
return '/%([0-9A-Fa-f]{2})/'; | |
} | |
# gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" | |
# | |
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" | |
# / "*" / "+" / "," / ";" / "=" | |
# | |
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" | |
function Auth_OpenID_getURLIllegalCharRE() | |
{ | |
return "/([^-A-Za-z0-9:\/\?#\[\]@\!\$&'\(\)\*\+,;=\._~\%])/"; | |
} | |
function Auth_OpenID_getUnreserved() | |
{ | |
$_unreserved = array(); | |
for ($i = 0; $i < 256; $i++) { | |
$_unreserved[$i] = false; | |
} | |
for ($i = ord('A'); $i <= ord('Z'); $i++) { | |
$_unreserved[$i] = true; | |
} | |
for ($i = ord('0'); $i <= ord('9'); $i++) { | |
$_unreserved[$i] = true; | |
} | |
for ($i = ord('a'); $i <= ord('z'); $i++) { | |
$_unreserved[$i] = true; | |
} | |
$_unreserved[ord('-')] = true; | |
$_unreserved[ord('.')] = true; | |
$_unreserved[ord('_')] = true; | |
$_unreserved[ord('~')] = true; | |
return $_unreserved; | |
} | |
function Auth_OpenID_getEscapeRE() | |
{ | |
$parts = array(); | |
foreach (array_merge(Auth_Yadis_getUCSChars(), | |
Auth_Yadis_getIPrivateChars()) as $pair) { | |
list($m, $n) = $pair; | |
$parts[] = sprintf("%s-%s", chr($m), chr($n)); | |
} | |
return sprintf('[%s]', implode('', $parts)); | |
} | |
function Auth_OpenID_pct_encoded_replace_unreserved($mo) | |
{ | |
$_unreserved = Auth_OpenID_getUnreserved(); | |
$i = intval($mo[1], 16); | |
if ($_unreserved[$i]) { | |
return chr($i); | |
} else { | |
return strtoupper($mo[0]); | |
} | |
return $mo[0]; | |
} | |
function Auth_OpenID_pct_encoded_replace($mo) | |
{ | |
return chr(intval($mo[1], 16)); | |
} | |
function Auth_OpenID_remove_dot_segments($path) | |
{ | |
$result_segments = array(); | |
while ($path) { | |
if (Auth_Yadis_startswith($path, '../')) { | |
$path = substr($path, 3); | |
} else if (Auth_Yadis_startswith($path, './')) { | |
$path = substr($path, 2); | |
} else if (Auth_Yadis_startswith($path, '/./')) { | |
$path = substr($path, 2); | |
} else if ($path == '/.') { | |
$path = '/'; | |
} else if (Auth_Yadis_startswith($path, '/../')) { | |
$path = substr($path, 3); | |
if ($result_segments) { | |
array_pop($result_segments); | |
} | |
} else if ($path == '/..') { | |
$path = '/'; | |
if ($result_segments) { | |
array_pop($result_segments); | |
} | |
} else if (($path == '..') || | |
($path == '.')) { | |
$path = ''; | |
} else { | |
$i = 0; | |
if ($path[0] == '/') { | |
$i = 1; | |
} | |
$i = strpos($path, '/', $i); | |
if ($i === false) { | |
$i = strlen($path); | |
} | |
$result_segments[] = substr($path, 0, $i); | |
$path = substr($path, $i); | |
} | |
} | |
return implode('', $result_segments); | |
} | |
function Auth_OpenID_urinorm($uri) | |
{ | |
$uri_matches = array(); | |
preg_match(Auth_OpenID_getURIPattern(), $uri, $uri_matches); | |
if (count($uri_matches) < 9) { | |
for ($i = count($uri_matches); $i <= 9; $i++) { | |
$uri_matches[] = ''; | |
} | |
} | |
$illegal_matches = array(); | |
preg_match(Auth_OpenID_getURLIllegalCharRE(), | |
$uri, $illegal_matches); | |
if ($illegal_matches) { | |
return null; | |
} | |
$scheme = $uri_matches[2]; | |
if ($scheme) { | |
$scheme = strtolower($scheme); | |
} | |
$scheme = $uri_matches[2]; | |
if ($scheme === '') { | |
// No scheme specified | |
return null; | |
} | |
$scheme = strtolower($scheme); | |
if (!in_array($scheme, array('http', 'https'))) { | |
// Not an absolute HTTP or HTTPS URI | |
return null; | |
} | |
$authority = $uri_matches[4]; | |
if ($authority === '') { | |
// Not an absolute URI | |
return null; | |
} | |
$authority_matches = array(); | |
preg_match(Auth_OpenID_getAuthorityPattern(), | |
$authority, $authority_matches); | |
if (count($authority_matches) === 0) { | |
// URI does not have a valid authority | |
return null; | |
} | |
if (count($authority_matches) < 4) { | |
for ($i = count($authority_matches); $i <= 4; $i++) { | |
$authority_matches[] = ''; | |
} | |
} | |
list($_whole, $userinfo, $host, $port) = $authority_matches; | |
if ($userinfo === null) { | |
$userinfo = ''; | |
} | |
if (strpos($host, '%') !== -1) { | |
$host = strtolower($host); | |
$host = preg_replace_callback( | |
Auth_OpenID_getEncodedPattern(), | |
'Auth_OpenID_pct_encoded_replace', $host); | |
// NO IDNA. | |
// $host = unicode($host, 'utf-8').encode('idna'); | |
} else { | |
$host = strtolower($host); | |
} | |
if ($port) { | |
if (($port == ':') || | |
($scheme == 'http' && $port == ':80') || | |
($scheme == 'https' && $port == ':443')) { | |
$port = ''; | |
} | |
} else { | |
$port = ''; | |
} | |
$authority = $userinfo . $host . $port; | |
$path = $uri_matches[5]; | |
$path = preg_replace_callback( | |
Auth_OpenID_getEncodedPattern(), | |
'Auth_OpenID_pct_encoded_replace_unreserved', $path); | |
$path = Auth_OpenID_remove_dot_segments($path); | |
if (!$path) { | |
$path = '/'; | |
} | |
$query = $uri_matches[6]; | |
if ($query === null) { | |
$query = ''; | |
} | |
$fragment = $uri_matches[8]; | |
if ($fragment === null) { | |
$fragment = ''; | |
} | |
return $scheme . '://' . $authority . $path . $query . $fragment; | |
} | |
<?php | |
/** | |
* This module contains the HTTP fetcher interface | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Require logging functionality | |
*/ | |
require_once "Auth/OpenID.php"; | |
define('Auth_OpenID_FETCHER_MAX_RESPONSE_KB', 1024); | |
define('Auth_OpenID_USER_AGENT', | |
'php-openid/'.Auth_OpenID_VERSION.' (php/'.phpversion().')'); | |
class Auth_Yadis_HTTPResponse { | |
function Auth_Yadis_HTTPResponse($final_url = null, $status = null, | |
$headers = null, $body = null) | |
{ | |
$this->final_url = $final_url; | |
$this->status = $status; | |
$this->headers = $headers; | |
$this->body = $body; | |
} | |
} | |
/** | |
* This class is the interface for HTTP fetchers the Yadis library | |
* uses. This interface is only important if you need to write a new | |
* fetcher for some reason. | |
* | |
* @access private | |
* @package OpenID | |
*/ | |
class Auth_Yadis_HTTPFetcher { | |
var $timeout = 20; // timeout in seconds. | |
/** | |
* Return whether a URL can be fetched. Returns false if the URL | |
* scheme is not allowed or is not supported by this fetcher | |
* implementation; returns true otherwise. | |
* | |
* @return bool | |
*/ | |
function canFetchURL($url) | |
{ | |
if ($this->isHTTPS($url) && !$this->supportsSSL()) { | |
Auth_OpenID::log("HTTPS URL unsupported fetching %s", | |
$url); | |
return false; | |
} | |
if (!$this->allowedURL($url)) { | |
Auth_OpenID::log("URL fetching not allowed for '%s'", | |
$url); | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Return whether a URL should be allowed. Override this method to | |
* conform to your local policy. | |
* | |
* By default, will attempt to fetch any http or https URL. | |
*/ | |
function allowedURL($url) | |
{ | |
return $this->URLHasAllowedScheme($url); | |
} | |
/** | |
* Does this fetcher implementation (and runtime) support fetching | |
* HTTPS URLs? May inspect the runtime environment. | |
* | |
* @return bool $support True if this fetcher supports HTTPS | |
* fetching; false if not. | |
*/ | |
function supportsSSL() | |
{ | |
trigger_error("not implemented", E_USER_ERROR); | |
} | |
/** | |
* Is this an https URL? | |
* | |
* @access private | |
*/ | |
function isHTTPS($url) | |
{ | |
return (bool)preg_match('/^https:\/\//i', $url); | |
} | |
/** | |
* Is this an http or https URL? | |
* | |
* @access private | |
*/ | |
function URLHasAllowedScheme($url) | |
{ | |
return (bool)preg_match('/^https?:\/\//i', $url); | |
} | |
/** | |
* @access private | |
*/ | |
function _findRedirect($headers, $url) | |
{ | |
foreach ($headers as $line) { | |
if (strpos(strtolower($line), "location: ") === 0) { | |
$parts = explode(" ", $line, 2); | |
$loc = $parts[1]; | |
$ppos = strpos($loc, "://"); | |
if ($ppos === false || $ppos > strpos($loc, "/")) { | |
/* no host; add it */ | |
$hpos = strpos($url, "://"); | |
$prt = substr($url, 0, $hpos+3); | |
$url = substr($url, $hpos+3); | |
if (substr($loc, 0, 1) == "/") { | |
/* absolute path */ | |
$fspos = strpos($url, "/"); | |
if ($fspos) $loc = $prt.substr($url, 0, $fspos).$loc; | |
else $loc = $prt.$url.$loc; | |
} else { | |
/* relative path */ | |
$pp = $prt; | |
while (1) { | |
$xpos = strpos($url, "/"); | |
if ($xpos === false) break; | |
$apos = strpos($url, "?"); | |
if ($apos !== false && $apos < $xpos) break; | |
$apos = strpos($url, "&"); | |
if ($apos !== false && $apos < $xpos) break; | |
$pp .= substr($url, 0, $xpos+1); | |
$url = substr($url, $xpos+1); | |
} | |
$loc = $pp.$loc; | |
} | |
} | |
return $loc; | |
} | |
} | |
return null; | |
} | |
/** | |
* Fetches the specified URL using optional extra headers and | |
* returns the server's response. | |
* | |
* @param string $url The URL to be fetched. | |
* @param array $extra_headers An array of header strings | |
* (e.g. "Accept: text/html"). | |
* @return mixed $result An array of ($code, $url, $headers, | |
* $body) if the URL could be fetched; null if the URL does not | |
* pass the URLHasAllowedScheme check or if the server's response | |
* is malformed. | |
*/ | |
function get($url, $headers = null) | |
{ | |
trigger_error("not implemented", E_USER_ERROR); | |
} | |
} | |
<?php | <?php |
/** | /** |
* Yadis service manager to be used during yadis-driven authentication | * Yadis service manager to be used during yadis-driven authentication |
* attempts. | * attempts. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
/** | /** |
* The base session class used by the Auth_Yadis_Manager. This | * The base session class used by the Auth_Yadis_Manager. This |
* class wraps the default PHP session machinery and should be | * class wraps the default PHP session machinery and should be |
* subclassed if your application doesn't use PHP sessioning. | * subclassed if your application doesn't use PHP sessioning. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_PHPSession { | class Auth_Yadis_PHPSession { |
/** | /** |
* Set a session key/value pair. | * Set a session key/value pair. |
* | * |
* @param string $name The name of the session key to add. | * @param string $name The name of the session key to add. |
* @param string $value The value to add to the session. | * @param string $value The value to add to the session. |
*/ | */ |
function set($name, $value) | function set($name, $value) |
{ | { |
$_SESSION[$name] = $value; | $_SESSION[$name] = $value; |
} | } |
/** | /** |
* Get a key's value from the session. | * Get a key's value from the session. |
* | * |
* @param string $name The name of the key to retrieve. | * @param string $name The name of the key to retrieve. |
* @param string $default The optional value to return if the key | * @param string $default The optional value to return if the key |
* is not found in the session. | * is not found in the session. |
* @return string $result The key's value in the session or | * @return string $result The key's value in the session or |
* $default if it isn't found. | * $default if it isn't found. |
*/ | */ |
function get($name, $default=null) | function get($name, $default=null) |
{ | { |
if (array_key_exists($name, $_SESSION)) { | if (array_key_exists($name, $_SESSION)) { |
return $_SESSION[$name]; | return $_SESSION[$name]; |
} else { | } else { |
return $default; | return $default; |
} | } |
} | } |
/** | /** |
* Remove a key/value pair from the session. | * Remove a key/value pair from the session. |
* | * |
* @param string $name The name of the key to remove. | * @param string $name The name of the key to remove. |
*/ | */ |
function del($name) | function del($name) |
{ | { |
unset($_SESSION[$name]); | unset($_SESSION[$name]); |
} | } |
/** | /** |
* Return the contents of the session in array form. | * Return the contents of the session in array form. |
*/ | */ |
function contents() | function contents() |
{ | { |
return $_SESSION; | return $_SESSION; |
} | } |
} | } |
/** | /** |
* A session helper class designed to translate between arrays and | * A session helper class designed to translate between arrays and |
* objects. Note that the class used must have a constructor that | * objects. Note that the class used must have a constructor that |
* takes no parameters. This is not a general solution, but it works | * takes no parameters. This is not a general solution, but it works |
* for dumb objects that just need to have attributes set. The idea | * for dumb objects that just need to have attributes set. The idea |
* is that you'll subclass this and override $this->check($data) -> | * is that you'll subclass this and override $this->check($data) -> |
* bool to implement your own session data validation. | * bool to implement your own session data validation. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_SessionLoader { | class Auth_Yadis_SessionLoader { |
/** | /** |
* Override this. | * Override this. |
* | * |
* @access private | * @access private |
*/ | */ |
function check($data) | function check($data) |
{ | { |
return true; | return true; |
} | } |
/** | /** |
* Given a session data value (an array), this creates an object | * Given a session data value (an array), this creates an object |
* (returned by $this->newObject()) whose attributes and values | * (returned by $this->newObject()) whose attributes and values |
* are those in $data. Returns null if $data lacks keys found in | * are those in $data. Returns null if $data lacks keys found in |
* $this->requiredKeys(). Returns null if $this->check($data) | * $this->requiredKeys(). Returns null if $this->check($data) |
* evaluates to false. Returns null if $this->newObject() | * evaluates to false. Returns null if $this->newObject() |
* evaluates to false. | * evaluates to false. |
* | * |
* @access private | * @access private |
*/ | */ |
function fromSession($data) | function fromSession($data) |
{ | { |
if (!$data) { | if (!$data) { |
return null; | return null; |
} | } |
$required = $this->requiredKeys(); | $required = $this->requiredKeys(); |
foreach ($required as $k) { | foreach ($required as $k) { |
if (!array_key_exists($k, $data)) { | if (!array_key_exists($k, $data)) { |
return null; | return null; |
} | } |
} | } |
if (!$this->check($data)) { | if (!$this->check($data)) { |
return null; | return null; |
} | } |
$data = array_merge($data, $this->prepareForLoad($data)); | $data = array_merge($data, $this->prepareForLoad($data)); |
$obj = $this->newObject($data); | $obj = $this->newObject($data); |
if (!$obj) { | if (!$obj) { |
return null; | return null; |
} | } |
foreach ($required as $k) { | foreach ($required as $k) { |
$obj->$k = $data[$k]; | $obj->$k = $data[$k]; |
} | } |
return $obj; | return $obj; |
} | } |
/** | /** |
* Prepares the data array by making any necessary changes. | * Prepares the data array by making any necessary changes. |
* Returns an array whose keys and values will be used to update | * Returns an array whose keys and values will be used to update |
* the original data array before calling $this->newObject($data). | * the original data array before calling $this->newObject($data). |
* | * |
* @access private | * @access private |
*/ | */ |
function prepareForLoad($data) | function prepareForLoad($data) |
{ | { |
return array(); | return array(); |
} | } |
/** | /** |
* Returns a new instance of this loader's class, using the | * Returns a new instance of this loader's class, using the |
* session data to construct it if necessary. The object need | * session data to construct it if necessary. The object need |
* only be created; $this->fromSession() will take care of setting | * only be created; $this->fromSession() will take care of setting |
* the object's attributes. | * the object's attributes. |
* | * |
* @access private | * @access private |
*/ | */ |
function newObject($data) | function newObject($data) |
{ | { |
return null; | return null; |
} | } |
/** | /** |
* Returns an array of keys and values built from the attributes | * Returns an array of keys and values built from the attributes |
* of $obj. If $this->prepareForSave($obj) returns an array, its keys | * of $obj. If $this->prepareForSave($obj) returns an array, its keys |
* and values are used to update the $data array of attributes | * and values are used to update the $data array of attributes |
* from $obj. | * from $obj. |
* | * |
* @access private | * @access private |
*/ | */ |
function toSession($obj) | function toSession($obj) |
{ | { |
$data = array(); | $data = array(); |
foreach ($obj as $k => $v) { | foreach ($obj as $k => $v) { |
$data[$k] = $v; | $data[$k] = $v; |
} | } |
$extra = $this->prepareForSave($obj); | $extra = $this->prepareForSave($obj); |
if ($extra && is_array($extra)) { | if ($extra && is_array($extra)) { |
foreach ($extra as $k => $v) { | foreach ($extra as $k => $v) { |
$data[$k] = $v; | $data[$k] = $v; |
} | } |
} | } |
return $data; | return $data; |
} | } |
/** | /** |
* Override this. | * Override this. |
* | * |
* @access private | * @access private |
*/ | */ |
function prepareForSave($obj) | function prepareForSave($obj) |
{ | { |
return array(); | return array(); |
} | } |
} | } |
/** | /** |
* A concrete loader implementation for Auth_OpenID_ServiceEndpoints. | * A concrete loader implementation for Auth_OpenID_ServiceEndpoints. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_OpenID_ServiceEndpointLoader extends Auth_Yadis_SessionLoader { | class Auth_OpenID_ServiceEndpointLoader extends Auth_Yadis_SessionLoader { |
function newObject($data) | function newObject($data) |
{ | { |
return new Auth_OpenID_ServiceEndpoint(); | return new Auth_OpenID_ServiceEndpoint(); |
} | } |
function requiredKeys() | function requiredKeys() |
{ | { |
$obj = new Auth_OpenID_ServiceEndpoint(); | $obj = new Auth_OpenID_ServiceEndpoint(); |
$data = array(); | $data = array(); |
foreach ($obj as $k => $v) { | foreach ($obj as $k => $v) { |
$data[] = $k; | $data[] = $k; |
} | } |
return $data; | return $data; |
} | } |
function check($data) | function check($data) |
{ | { |
return is_array($data['type_uris']); | return is_array($data['type_uris']); |
} | } |
} | } |
/** | /** |
* A concrete loader implementation for Auth_Yadis_Managers. | * A concrete loader implementation for Auth_Yadis_Managers. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_ManagerLoader extends Auth_Yadis_SessionLoader { | class Auth_Yadis_ManagerLoader extends Auth_Yadis_SessionLoader { |
function requiredKeys() | function requiredKeys() |
{ | { |
return array('starting_url', | return array('starting_url', |
'yadis_url', | 'yadis_url', |
'services', | 'services', |
'session_key', | 'session_key', |
'_current', | '_current', |
'stale'); | 'stale'); |
} | } |
function newObject($data) | function newObject($data) |
{ | { |
return new Auth_Yadis_Manager($data['starting_url'], | return new Auth_Yadis_Manager($data['starting_url'], |
$data['yadis_url'], | $data['yadis_url'], |
$data['services'], | $data['services'], |
$data['session_key']); | $data['session_key']); |
} | } |
function check($data) | function check($data) |
{ | { |
return is_array($data['services']); | return is_array($data['services']); |
} | } |
function prepareForLoad($data) | function prepareForLoad($data) |
{ | { |
$loader = new Auth_OpenID_ServiceEndpointLoader(); | $loader = new Auth_OpenID_ServiceEndpointLoader(); |
$services = array(); | $services = array(); |
foreach ($data['services'] as $s) { | foreach ($data['services'] as $s) { |
$services[] = $loader->fromSession($s); | $services[] = $loader->fromSession($s); |
} | } |
return array('services' => $services); | return array('services' => $services); |
} | } |
function prepareForSave($obj) | function prepareForSave($obj) |
{ | { |
$loader = new Auth_OpenID_ServiceEndpointLoader(); | $loader = new Auth_OpenID_ServiceEndpointLoader(); |
$services = array(); | $services = array(); |
foreach ($obj->services as $s) { | foreach ($obj->services as $s) { |
$services[] = $loader->toSession($s); | $services[] = $loader->toSession($s); |
} | } |
return array('services' => $services); | return array('services' => $services); |
} | } |
} | } |
/** | /** |
* The Yadis service manager which stores state in a session and | * The Yadis service manager which stores state in a session and |
* iterates over <Service> elements in a Yadis XRDS document and lets | * iterates over <Service> elements in a Yadis XRDS document and lets |
* a caller attempt to use each one. This is used by the Yadis | * a caller attempt to use each one. This is used by the Yadis |
* library internally. | * library internally. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_Manager { | class Auth_Yadis_Manager { |
/** | /** |
* Intialize a new yadis service manager. | * Intialize a new yadis service manager. |
* | * |
* @access private | * @access private |
*/ | */ |
function Auth_Yadis_Manager($starting_url, $yadis_url, | function Auth_Yadis_Manager($starting_url, $yadis_url, |
$services, $session_key) | $services, $session_key) |
{ | { |
// The URL that was used to initiate the Yadis protocol | // The URL that was used to initiate the Yadis protocol |
$this->starting_url = $starting_url; | $this->starting_url = $starting_url; |
// The URL after following redirects (the identifier) | // The URL after following redirects (the identifier) |
$this->yadis_url = $yadis_url; | $this->yadis_url = $yadis_url; |
// List of service elements | // List of service elements |
$this->services = $services; | $this->services = $services; |
$this->session_key = $session_key; | $this->session_key = $session_key; |
// Reference to the current service object | // Reference to the current service object |
$this->_current = null; | $this->_current = null; |
// Stale flag for cleanup if PHP lib has trouble. | // Stale flag for cleanup if PHP lib has trouble. |
$this->stale = false; | $this->stale = false; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function length() | function length() |
{ | { |
// How many untried services remain? | // How many untried services remain? |
return count($this->services); | return count($this->services); |
} | } |
/** | /** |
* Return the next service | * Return the next service |
* | * |
* $this->current() will continue to return that service until the | * $this->current() will continue to return that service until the |
* next call to this method. | * next call to this method. |
*/ | */ |
function nextService() | function nextService() |
{ | { |
if ($this->services) { | if ($this->services) { |
$this->_current = array_shift($this->services); | $this->_current = array_shift($this->services); |
} else { | } else { |
$this->_current = null; | $this->_current = null; |
} | } |
return $this->_current; | return $this->_current; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function current() | function current() |
{ | { |
// Return the current service. | // Return the current service. |
// Returns None if there are no services left. | // Returns None if there are no services left. |
return $this->_current; | return $this->_current; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function forURL($url) | function forURL($url) |
{ | { |
return in_array($url, array($this->starting_url, $this->yadis_url)); | return in_array($url, array($this->starting_url, $this->yadis_url)); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function started() | function started() |
{ | { |
// Has the first service been returned? | // Has the first service been returned? |
return $this->_current !== null; | return $this->_current !== null; |
} | } |
} | } |
/** | /** |
* State management for discovery. | * State management for discovery. |
* | * |
* High-level usage pattern is to call .getNextService(discover) in | * High-level usage pattern is to call .getNextService(discover) in |
* order to find the next available service for this user for this | * order to find the next available service for this user for this |
* session. Once a request completes, call .cleanup() to clean up the | * session. Once a request completes, call .cleanup() to clean up the |
* session state. | * session state. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_Discovery { | class Auth_Yadis_Discovery { |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $DEFAULT_SUFFIX = 'auth'; | var $DEFAULT_SUFFIX = 'auth'; |
/** | /** |
* @access private | * @access private |
*/ | */ |
var $PREFIX = '_yadis_services_'; | var $PREFIX = '_yadis_services_'; |
/** | /** |
* Initialize a discovery object. | * Initialize a discovery object. |
* | * |
* @param Auth_Yadis_PHPSession $session An object which | * @param Auth_Yadis_PHPSession $session An object which |
* implements the Auth_Yadis_PHPSession API. | * implements the Auth_Yadis_PHPSession API. |
* @param string $url The URL on which to attempt discovery. | * @param string $url The URL on which to attempt discovery. |
* @param string $session_key_suffix The optional session key | * @param string $session_key_suffix The optional session key |
* suffix override. | * suffix override. |
*/ | */ |
function Auth_Yadis_Discovery($session, $url, | function Auth_Yadis_Discovery($session, $url, |
$session_key_suffix = null) | $session_key_suffix = null) |
{ | { |
/// Initialize a discovery object | /// Initialize a discovery object |
$this->session = $session; | $this->session = $session; |
$this->url = $url; | $this->url = $url; |
if ($session_key_suffix === null) { | if ($session_key_suffix === null) { |
$session_key_suffix = $this->DEFAULT_SUFFIX; | $session_key_suffix = $this->DEFAULT_SUFFIX; |
} | } |
$this->session_key_suffix = $session_key_suffix; | $this->session_key_suffix = $session_key_suffix; |
$this->session_key = $this->PREFIX . $this->session_key_suffix; | $this->session_key = $this->PREFIX . $this->session_key_suffix; |
} | } |
/** | /** |
* Return the next authentication service for the pair of | * Return the next authentication service for the pair of |
* user_input and session. This function handles fallback. | * user_input and session. This function handles fallback. |
*/ | */ |
function getNextService($discover_cb, $fetcher) | function getNextService($discover_cb, $fetcher) |
{ | { |
$manager = $this->getManager(); | $manager = $this->getManager(); |
if (!$manager || (!$manager->services)) { | if (!$manager || (!$manager->services)) { |
$this->destroyManager(); | $this->destroyManager(); |
list($yadis_url, $services) = call_user_func($discover_cb, | list($yadis_url, $services) = call_user_func($discover_cb, |
$this->url, | $this->url, |
&$fetcher); | $fetcher); |
$manager = $this->createManager($services, $yadis_url); | $manager = $this->createManager($services, $yadis_url); |
} | } |
if ($manager) { | if ($manager) { |
$loader = new Auth_Yadis_ManagerLoader(); | $loader = new Auth_Yadis_ManagerLoader(); |
$service = $manager->nextService(); | $service = $manager->nextService(); |
$this->session->set($this->session_key, | $this->session->set($this->session_key, |
serialize($loader->toSession($manager))); | serialize($loader->toSession($manager))); |
} else { | } else { |
$service = null; | $service = null; |
} | } |
return $service; | return $service; |
} | } |
/** | /** |
* Clean up Yadis-related services in the session and return the | * Clean up Yadis-related services in the session and return the |
* most-recently-attempted service from the manager, if one | * most-recently-attempted service from the manager, if one |
* exists. | * exists. |
* | * |
* @param $force True if the manager should be deleted regardless | * @param $force True if the manager should be deleted regardless |
* of whether it's a manager for $this->url. | * of whether it's a manager for $this->url. |
*/ | */ |
function cleanup($force=false) | function cleanup($force=false) |
{ | { |
$manager = $this->getManager($force); | $manager = $this->getManager($force); |
if ($manager) { | if ($manager) { |
$service = $manager->current(); | $service = $manager->current(); |
$this->destroyManager($force); | $this->destroyManager($force); |
} else { | } else { |
$service = null; | $service = null; |
} | } |
return $service; | return $service; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function getSessionKey() | function getSessionKey() |
{ | { |
// Get the session key for this starting URL and suffix | // Get the session key for this starting URL and suffix |
return $this->PREFIX . $this->session_key_suffix; | return $this->PREFIX . $this->session_key_suffix; |
} | } |
/** | /** |
* @access private | * @access private |
* | * |
* @param $force True if the manager should be returned regardless | * @param $force True if the manager should be returned regardless |
* of whether it's a manager for $this->url. | * of whether it's a manager for $this->url. |
*/ | */ |
function getManager($force=false) | function getManager($force=false) |
{ | { |
// Extract the YadisServiceManager for this object's URL and | // Extract the YadisServiceManager for this object's URL and |
// suffix from the session. | // suffix from the session. |
$manager_str = $this->session->get($this->getSessionKey()); | $manager_str = $this->session->get($this->getSessionKey()); |
$manager = null; | $manager = null; |
if ($manager_str !== null) { | if ($manager_str !== null) { |
$loader = new Auth_Yadis_ManagerLoader(); | $loader = new Auth_Yadis_ManagerLoader(); |
$manager = $loader->fromSession(unserialize($manager_str)); | $manager = $loader->fromSession(unserialize($manager_str)); |
} | } |
if ($manager && ($manager->forURL($this->url) || $force)) { | if ($manager && ($manager->forURL($this->url) || $force)) { |
return $manager; | return $manager; |
} | } |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function createManager($services, $yadis_url = null) | function createManager($services, $yadis_url = null) |
{ | { |
$key = $this->getSessionKey(); | $key = $this->getSessionKey(); |
if ($this->getManager()) { | if ($this->getManager()) { |
return $this->getManager(); | return $this->getManager(); |
} | } |
if ($services) { | if ($services) { |
$loader = new Auth_Yadis_ManagerLoader(); | $loader = new Auth_Yadis_ManagerLoader(); |
$manager = new Auth_Yadis_Manager($this->url, $yadis_url, | $manager = new Auth_Yadis_Manager($this->url, $yadis_url, |
$services, $key); | $services, $key); |
$this->session->set($this->session_key, | $this->session->set($this->session_key, |
serialize($loader->toSession($manager))); | serialize($loader->toSession($manager))); |
return $manager; | return $manager; |
} | } |
} | } |
/** | /** |
* @access private | * @access private |
* | * |
* @param $force True if the manager should be deleted regardless | * @param $force True if the manager should be deleted regardless |
* of whether it's a manager for $this->url. | * of whether it's a manager for $this->url. |
*/ | */ |
function destroyManager($force=false) | function destroyManager($force=false) |
{ | { |
if ($this->getManager($force) !== null) { | if ($this->getManager($force) !== null) { |
$key = $this->getSessionKey(); | $key = $this->getSessionKey(); |
$this->session->del($key); | $this->session->del($key); |
} | } |
} | } |
} | } |
<?php | |
/** | |
* Miscellaneous utility values and functions for OpenID and Yadis. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
function Auth_Yadis_getUCSChars() | |
{ | |
return array( | |
array(0xA0, 0xD7FF), | |
array(0xF900, 0xFDCF), | |
array(0xFDF0, 0xFFEF), | |
array(0x10000, 0x1FFFD), | |
array(0x20000, 0x2FFFD), | |
array(0x30000, 0x3FFFD), | |
array(0x40000, 0x4FFFD), | |
array(0x50000, 0x5FFFD), | |
array(0x60000, 0x6FFFD), | |
array(0x70000, 0x7FFFD), | |
array(0x80000, 0x8FFFD), | |
array(0x90000, 0x9FFFD), | |
array(0xA0000, 0xAFFFD), | |
array(0xB0000, 0xBFFFD), | |
array(0xC0000, 0xCFFFD), | |
array(0xD0000, 0xDFFFD), | |
array(0xE1000, 0xEFFFD) | |
); | |
} | |
function Auth_Yadis_getIPrivateChars() | |
{ | |
return array( | |
array(0xE000, 0xF8FF), | |
array(0xF0000, 0xFFFFD), | |
array(0x100000, 0x10FFFD) | |
); | |
} | |
function Auth_Yadis_pct_escape_unicode($char_match) | |
{ | |
$c = $char_match[0]; | |
$result = ""; | |
for ($i = 0; $i < strlen($c); $i++) { | |
$result .= "%".sprintf("%X", ord($c[$i])); | |
} | |
return $result; | |
} | |
function Auth_Yadis_startswith($s, $stuff) | |
{ | |
return strpos($s, $stuff) === 0; | |
} | |
<?php | |
/** | |
* This module contains the CURL-based HTTP fetcher implementation. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Interface import | |
*/ | |
require_once "Auth/Yadis/HTTPFetcher.php"; | |
require_once "Auth/OpenID.php"; | |
/** | |
* A paranoid {@link Auth_Yadis_HTTPFetcher} class which uses CURL | |
* for fetching. | |
* | |
* @package OpenID | |
*/ | |
class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher { | |
function Auth_Yadis_ParanoidHTTPFetcher() | |
{ | |
$this->reset(); | |
} | |
function reset() | |
{ | |
$this->headers = array(); | |
$this->data = ""; | |
} | |
/** | |
* @access private | |
*/ | |
function _writeHeader($ch, $header) | |
{ | |
array_push($this->headers, rtrim($header)); | |
return strlen($header); | |
} | |
/** | |
* @access private | |
*/ | |
function _writeData($ch, $data) | |
{ | |
if (strlen($this->data) > 1024*Auth_OpenID_FETCHER_MAX_RESPONSE_KB) { | |
return 0; | |
} else { | |
$this->data .= $data; | |
return strlen($data); | |
} | |
} | |
/** | |
* Does this fetcher support SSL URLs? | |
*/ | |
function supportsSSL() | |
{ | |
$v = curl_version(); | |
if(is_array($v)) { | |
return in_array('https', $v['protocols']); | |
} elseif (is_string($v)) { | |
return preg_match('/OpenSSL/i', $v); | |
} else { | |
return 0; | |
} | |
} | |
function get($url, $extra_headers = null) | |
{ | |
if (!$this->canFetchURL($url)) { | |
return null; | |
} | |
$stop = time() + $this->timeout; | |
$off = $this->timeout; | |
$redir = true; | |
while ($redir && ($off > 0)) { | |
$this->reset(); | |
$c = curl_init(); | |
if ($c === false) { | |
Auth_OpenID::log( | |
"curl_init returned false; could not " . | |
"initialize for URL '%s'", $url); | |
return null; | |
} | |
if (defined('CURLOPT_NOSIGNAL')) { | |
curl_setopt($c, CURLOPT_NOSIGNAL, true); | |
} | |
if (!$this->allowedURL($url)) { | |
Auth_OpenID::log("Fetching URL not allowed: %s", | |
$url); | |
return null; | |
} | |
curl_setopt($c, CURLOPT_WRITEFUNCTION, | |
array($this, "_writeData")); | |
curl_setopt($c, CURLOPT_HEADERFUNCTION, | |
array($this, "_writeHeader")); | |
if ($extra_headers) { | |
curl_setopt($c, CURLOPT_HTTPHEADER, $extra_headers); | |
} | |
$cv = curl_version(); | |
if(is_array($cv)) { | |
$curl_user_agent = 'curl/'.$cv['version']; | |
} else { | |
$curl_user_agent = $cv; | |
} | |
curl_setopt($c, CURLOPT_USERAGENT, | |
Auth_OpenID_USER_AGENT.' '.$curl_user_agent); | |
curl_setopt($c, CURLOPT_TIMEOUT, $off); | |
curl_setopt($c, CURLOPT_URL, $url); | |
if (defined('Auth_OpenID_VERIFY_HOST')) { | |
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true); | |
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2); | |
} | |
curl_exec($c); | |
$code = curl_getinfo($c, CURLINFO_HTTP_CODE); | |
$body = $this->data; | |
$headers = $this->headers; | |
if (!$code) { | |
Auth_OpenID::log("Got no response code when fetching %s", $url); | |
Auth_OpenID::log("CURL error (%s): %s", | |
curl_errno($c), curl_error($c)); | |
return null; | |
} | |
if (in_array($code, array(301, 302, 303, 307))) { | |
$url = $this->_findRedirect($headers, $url); | |
$redir = true; | |
} else { | |
$redir = false; | |
curl_close($c); | |
if (defined('Auth_OpenID_VERIFY_HOST') && | |
$this->isHTTPS($url)) { | |
Auth_OpenID::log('OpenID: Verified SSL host %s using '. | |
'curl/get', $url); | |
} | |
$new_headers = array(); | |
foreach ($headers as $header) { | |
if (strpos($header, ': ')) { | |
list($name, $value) = explode(': ', $header, 2); | |
$new_headers[$name] = $value; | |
} | |
} | |
Auth_OpenID::log( | |
"Successfully fetched '%s': GET response code %s", | |
$url, $code); | |
return new Auth_Yadis_HTTPResponse($url, $code, | |
$new_headers, $body); | |
} | |
$off = $stop - time(); | |
} | |
return null; | |
} | |
function post($url, $body, $extra_headers = null) | |
{ | |
if (!$this->canFetchURL($url)) { | |
return null; | |
} | |
$this->reset(); | |
$c = curl_init(); | |
if (defined('CURLOPT_NOSIGNAL')) { | |
curl_setopt($c, CURLOPT_NOSIGNAL, true); | |
} | |
curl_setopt($c, CURLOPT_POST, true); | |
curl_setopt($c, CURLOPT_POSTFIELDS, $body); | |
curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout); | |
curl_setopt($c, CURLOPT_URL, $url); | |
curl_setopt($c, CURLOPT_WRITEFUNCTION, | |
array($this, "_writeData")); | |
if (defined('Auth_OpenID_VERIFY_HOST')) { | |
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true); | |
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2); | |
} | |
curl_exec($c); | |
$code = curl_getinfo($c, CURLINFO_HTTP_CODE); | |
if (!$code) { | |
Auth_OpenID::log("Got no response code when fetching %s", $url); | |
Auth_OpenID::log("CURL error (%s): %s", | |
curl_errno($c), curl_error($c)); | |
return null; | |
} | |
if (defined('Auth_OpenID_VERIFY_HOST') && $this->isHTTPS($url)) { | |
Auth_OpenID::log('OpenID: Verified SSL host %s using '. | |
'curl/post', $url); | |
} | |
$body = $this->data; | |
curl_close($c); | |
$new_headers = $extra_headers; | |
foreach ($this->headers as $header) { | |
if (strpos($header, ': ')) { | |
list($name, $value) = explode(': ', $header, 2); | |
$new_headers[$name] = $value; | |
} | |
} | |
Auth_OpenID::log("Successfully fetched '%s': POST response code %s", | |
$url, $code); | |
return new Auth_Yadis_HTTPResponse($url, $code, | |
$new_headers, $body); | |
} | |
} | |
<?php | |
/** | |
* This is the HTML pseudo-parser for the Yadis library. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* This class is responsible for scanning an HTML string to find META | |
* tags and their attributes. This is used by the Yadis discovery | |
* process. This class must be instantiated to be used. | |
* | |
* @package OpenID | |
*/ | |
class Auth_Yadis_ParseHTML { | |
/** | |
* @access private | |
*/ | |
var $_re_flags = "si"; | |
/** | |
* @access private | |
*/ | |
var $_removed_re = | |
"<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b(?!:)[^>]*>.*?<\/script>"; | |
/** | |
* @access private | |
*/ | |
var $_tag_expr = "<%s%s(?:\s.*?)?%s>"; | |
/** | |
* @access private | |
*/ | |
var $_attr_find = '\b([-\w]+)=(".*?"|\'.*?\'|.+?)[\/\s>]'; | |
function Auth_Yadis_ParseHTML() | |
{ | |
$this->_attr_find = sprintf("/%s/%s", | |
$this->_attr_find, | |
$this->_re_flags); | |
$this->_removed_re = sprintf("/%s/%s", | |
$this->_removed_re, | |
$this->_re_flags); | |
$this->_entity_replacements = array( | |
'amp' => '&', | |
'lt' => '<', | |
'gt' => '>', | |
'quot' => '"' | |
); | |
$this->_ent_replace = | |
sprintf("&(%s);", implode("|", | |
$this->_entity_replacements)); | |
} | |
/** | |
* Replace HTML entities (amp, lt, gt, and quot) as well as | |
* numeric entities (e.g. #x9f;) with their actual values and | |
* return the new string. | |
* | |
* @access private | |
* @param string $str The string in which to look for entities | |
* @return string $new_str The new string entities decoded | |
*/ | |
function replaceEntities($str) | |
{ | |
foreach ($this->_entity_replacements as $old => $new) { | |
$str = preg_replace(sprintf("/&%s;/", $old), $new, $str); | |
} | |
// Replace numeric entities because html_entity_decode doesn't | |
// do it for us. | |
$str = preg_replace('~&#x([0-9a-f]+);~ei', 'chr(hexdec("\\1"))', $str); | |
$str = preg_replace('~&#([0-9]+);~e', 'chr(\\1)', $str); | |
return $str; | |
} | |
/** | |
* Strip single and double quotes off of a string, if they are | |
* present. | |
* | |
* @access private | |
* @param string $str The original string | |
* @return string $new_str The new string with leading and | |
* trailing quotes removed | |
*/ | |
function removeQuotes($str) | |
{ | |
$matches = array(); | |
$double = '/^"(.*)"$/'; | |
$single = "/^\'(.*)\'$/"; | |
if (preg_match($double, $str, $matches)) { | |
return $matches[1]; | |
} else if (preg_match($single, $str, $matches)) { | |
return $matches[1]; | |
} else { | |
return $str; | |
} | |
} | |
/** | |
* Create a regular expression that will match an opening | |
* or closing tag from a set of names. | |
* | |
* @access private | |
* @param mixed $tag_names Tag names to match | |
* @param mixed $close false/0 = no, true/1 = yes, other = maybe | |
* @param mixed $self_close false/0 = no, true/1 = yes, other = maybe | |
* @return string $regex A regular expression string to be used | |
* in, say, preg_match. | |
*/ | |
function tagPattern($tag_names, $close, $self_close) | |
{ | |
if (is_array($tag_names)) { | |
$tag_names = '(?:'.implode('|',$tag_names).')'; | |
} | |
if ($close) { | |
$close = '\/' . (($close == 1)? '' : '?'); | |
} else { | |
$close = ''; | |
} | |
if ($self_close) { | |
$self_close = '(?:\/\s*)' . (($self_close == 1)? '' : '?'); | |
} else { | |
$self_close = ''; | |
} | |
$expr = sprintf($this->_tag_expr, $close, $tag_names, $self_close); | |
return sprintf("/%s/%s", $expr, $this->_re_flags); | |
} | |
/** | |
* Given an HTML document string, this finds all the META tags in | |
* the document, provided they are found in the | |
* <HTML><HEAD>...</HEAD> section of the document. The <HTML> tag | |
* may be missing. | |
* | |
* @access private | |
* @param string $html_string An HTMl document string | |
* @return array $tag_list Array of tags; each tag is an array of | |
* attribute -> value. | |
*/ | |
function getMetaTags($html_string) | |
{ | |
$html_string = preg_replace($this->_removed_re, | |
"", | |
$html_string); | |
$key_tags = array($this->tagPattern('html', false, false), | |
$this->tagPattern('head', false, false), | |
$this->tagPattern('head', true, false), | |
$this->tagPattern('html', true, false), | |
$this->tagPattern(array( | |
'body', 'frameset', 'frame', 'p', 'div', | |
'table','span','a'), 'maybe', 'maybe')); | |
$key_tags_pos = array(); | |
foreach ($key_tags as $pat) { | |
$matches = array(); | |
preg_match($pat, $html_string, $matches, PREG_OFFSET_CAPTURE); | |
if($matches) { | |
$key_tags_pos[] = $matches[0][1]; | |
} else { | |
$key_tags_pos[] = null; | |
} | |
} | |
// no opening head tag | |
if (is_null($key_tags_pos[1])) { | |
return array(); | |
} | |
// the effective </head> is the min of the following | |
if (is_null($key_tags_pos[2])) { | |
$key_tags_pos[2] = strlen($html_string); | |
} | |
foreach (array($key_tags_pos[3], $key_tags_pos[4]) as $pos) { | |
if (!is_null($pos) && $pos < $key_tags_pos[2]) { | |
$key_tags_pos[2] = $pos; | |
} | |
} | |
// closing head tag comes before opening head tag | |
if ($key_tags_pos[1] > $key_tags_pos[2]) { | |
return array(); | |
} | |
// if there is an opening html tag, make sure the opening head tag | |
// comes after it | |
if (!is_null($key_tags_pos[0]) && $key_tags_pos[1] < $key_tags_pos[0]) { | |
return array(); | |
} | |
$html_string = substr($html_string, $key_tags_pos[1], | |
($key_tags_pos[2]-$key_tags_pos[1])); | |
$link_data = array(); | |
$link_matches = array(); | |
if (!preg_match_all($this->tagPattern('meta', false, 'maybe'), | |
$html_string, $link_matches)) { | |
return array(); | |
} | |
foreach ($link_matches[0] as $link) { | |
$attr_matches = array(); | |
preg_match_all($this->_attr_find, $link, $attr_matches); | |
$link_attrs = array(); | |
foreach ($attr_matches[0] as $index => $full_match) { | |
$name = $attr_matches[1][$index]; | |
$value = $this->replaceEntities( | |
$this->removeQuotes($attr_matches[2][$index])); | |
$link_attrs[strtolower($name)] = $value; | |
} | |
$link_data[] = $link_attrs; | |
} | |
return $link_data; | |
} | |
/** | |
* Looks for a META tag with an "http-equiv" attribute whose value | |
* is one of ("x-xrds-location", "x-yadis-location"), ignoring | |
* case. If such a META tag is found, its "content" attribute | |
* value is returned. | |
* | |
* @param string $html_string An HTML document in string format | |
* @return mixed $content The "content" attribute value of the | |
* META tag, if found, or null if no such tag was found. | |
*/ | |
function getHTTPEquiv($html_string) | |
{ | |
$meta_tags = $this->getMetaTags($html_string); | |
if ($meta_tags) { | |
foreach ($meta_tags as $tag) { | |
if (array_key_exists('http-equiv', $tag) && | |
(in_array(strtolower($tag['http-equiv']), | |
array('x-xrds-location', 'x-yadis-location'))) && | |
array_key_exists('content', $tag)) { | |
return $tag['content']; | |
} | |
} | |
} | |
return null; | |
} | |
} | |
<?php | |
/** | |
* This module contains the plain non-curl HTTP fetcher | |
* implementation. | |
* | |
* PHP versions 4 and 5 | |
* | |
* LICENSE: See the COPYING file included in this distribution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
/** | |
* Interface import | |
*/ | |
require_once "Auth/Yadis/HTTPFetcher.php"; | |
/** | |
* This class implements a plain, hand-built socket-based fetcher | |
* which will be used in the event that CURL is unavailable. | |
* | |
* @package OpenID | |
*/ | |
class Auth_Yadis_PlainHTTPFetcher extends Auth_Yadis_HTTPFetcher { | |
/** | |
* Does this fetcher support SSL URLs? | |
*/ | |
function supportsSSL() | |
{ | |
return function_exists('openssl_open'); | |
} | |
function get($url, $extra_headers = null) | |
{ | |
if (!$this->canFetchURL($url)) { | |
return null; | |
} | |
$redir = true; | |
$stop = time() + $this->timeout; | |
$off = $this->timeout; | |
while ($redir && ($off > 0)) { | |
$parts = parse_url($url); | |
$specify_port = true; | |
// Set a default port. | |
if (!array_key_exists('port', $parts)) { | |
$specify_port = false; | |
if ($parts['scheme'] == 'http') { | |
$parts['port'] = 80; | |
} elseif ($parts['scheme'] == 'https') { | |
$parts['port'] = 443; | |
} else { | |
return null; | |
} | |
} | |
if (!array_key_exists('path', $parts)) { | |
$parts['path'] = '/'; | |
} | |
$host = $parts['host']; | |
if ($parts['scheme'] == 'https') { | |
$host = 'ssl://' . $host; | |
} | |
$user_agent = Auth_OpenID_USER_AGENT; | |
$headers = array( | |
"GET ".$parts['path']. | |
(array_key_exists('query', $parts) ? | |
"?".$parts['query'] : ""). | |
" HTTP/1.0", | |
"User-Agent: $user_agent", | |
"Host: ".$parts['host']. | |
($specify_port ? ":".$parts['port'] : ""), | |
"Port: ".$parts['port']); | |
$errno = 0; | |
$errstr = ''; | |
if ($extra_headers) { | |
foreach ($extra_headers as $h) { | |
$headers[] = $h; | |
} | |
} | |
@$sock = fsockopen($host, $parts['port'], $errno, $errstr, | |
$this->timeout); | |
if ($sock === false) { | |
return false; | |
} | |
stream_set_timeout($sock, $this->timeout); | |
fputs($sock, implode("\r\n", $headers) . "\r\n\r\n"); | |
$data = ""; | |
$kilobytes = 0; | |
while (!feof($sock) && | |
$kilobytes < Auth_OpenID_FETCHER_MAX_RESPONSE_KB ) { | |
$data .= fgets($sock, 1024); | |
$kilobytes += 1; | |
} | |
fclose($sock); | |
// Split response into header and body sections | |
list($headers, $body) = explode("\r\n\r\n", $data, 2); | |
$headers = explode("\r\n", $headers); | |
$http_code = explode(" ", $headers[0]); | |
$code = $http_code[1]; | |
if (in_array($code, array('301', '302'))) { | |
$url = $this->_findRedirect($headers, $url); | |
$redir = true; | |
} else { | |
$redir = false; | |
} | |
$off = $stop - time(); | |
} | |
$new_headers = array(); | |
foreach ($headers as $header) { | |
if (preg_match("/:/", $header)) { | |
$parts = explode(": ", $header, 2); | |
if (count($parts) == 2) { | |
list($name, $value) = $parts; | |
$new_headers[$name] = $value; | |
} | |
} | |
} | |
return new Auth_Yadis_HTTPResponse($url, $code, $new_headers, $body); | |
} | |
function post($url, $body, $extra_headers = null) | |
{ | |
if (!$this->canFetchURL($url)) { | |
return null; | |
} | |
$parts = parse_url($url); | |
$headers = array(); | |
$post_path = $parts['path']; | |
if (isset($parts['query'])) { | |
$post_path .= '?' . $parts['query']; | |
} | |
$headers[] = "POST ".$post_path." HTTP/1.0"; | |
$headers[] = "Host: " . $parts['host']; | |
$headers[] = "Content-type: application/x-www-form-urlencoded"; | |
$headers[] = "Content-length: " . strval(strlen($body)); | |
if ($extra_headers && | |
is_array($extra_headers)) { | |
$headers = array_merge($headers, $extra_headers); | |
} | |
// Join all headers together. | |
$all_headers = implode("\r\n", $headers); | |
// Add headers, two newlines, and request body. | |
$request = $all_headers . "\r\n\r\n" . $body; | |
// Set a default port. | |
if (!array_key_exists('port', $parts)) { | |
if ($parts['scheme'] == 'http') { | |
$parts['port'] = 80; | |
} elseif ($parts['scheme'] == 'https') { | |
$parts['port'] = 443; | |
} else { | |
return null; | |
} | |
} | |
if ($parts['scheme'] == 'https') { | |
$parts['host'] = sprintf("ssl://%s", $parts['host']); | |
} | |
// Connect to the remote server. | |
$errno = 0; | |
$errstr = ''; | |
$sock = fsockopen($parts['host'], $parts['port'], $errno, $errstr, | |
$this->timeout); | |
if ($sock === false) { | |
return null; | |
} | |
stream_set_timeout($sock, $this->timeout); | |
// Write the POST request. | |
fputs($sock, $request); | |
// Get the response from the server. | |
$response = ""; | |
while (!feof($sock)) { | |
if ($data = fgets($sock, 128)) { | |
$response .= $data; | |
} else { | |
break; | |
} | |
} | |
// Split the request into headers and body. | |
list($headers, $response_body) = explode("\r\n\r\n", $response, 2); | |
$headers = explode("\r\n", $headers); | |
// Expect the first line of the headers data to be something | |
// like HTTP/1.1 200 OK. Split the line on spaces and take | |
// the second token, which should be the return code. | |
$http_code = explode(" ", $headers[0]); | |
$code = $http_code[1]; | |
$new_headers = array(); | |
foreach ($headers as $header) { | |
if (preg_match("/:/", $header)) { | |
list($name, $value) = explode(": ", $header, 2); | |
$new_headers[$name] = $value; | |
} | |
} | |
return new Auth_Yadis_HTTPResponse($url, $code, | |
$new_headers, $response_body); | |
} | |
} | |
<?php | |
/** | |
* XML-parsing classes to wrap the domxml and DOM extensions for PHP 4 | |
* and 5, respectively. | |
* | |
* @package OpenID | |
*/ | |
/** | |
* The base class for wrappers for available PHP XML-parsing | |
* extensions. To work with this Yadis library, subclasses of this | |
* class MUST implement the API as defined in the remarks for this | |
* class. Subclasses of Auth_Yadis_XMLParser are used to wrap | |
* particular PHP XML extensions such as 'domxml'. These are used | |
* internally by the library depending on the availability of | |
* supported PHP XML extensions. | |
* | |
* @package OpenID | |
*/ | |
class Auth_Yadis_XMLParser { | |
/** | |
* Initialize an instance of Auth_Yadis_XMLParser with some | |
* XML and namespaces. This SHOULD NOT be overridden by | |
* subclasses. | |
* | |
* @param string $xml_string A string of XML to be parsed. | |
* @param array $namespace_map An array of ($ns_name => $ns_uri) | |
* to be registered with the XML parser. May be empty. | |
* @return boolean $result True if the initialization and | |
* namespace registration(s) succeeded; false otherwise. | |
*/ | |
function init($xml_string, $namespace_map) | |
{ | |
if (!$this->setXML($xml_string)) { | |
return false; | |
} | |
foreach ($namespace_map as $prefix => $uri) { | |
if (!$this->registerNamespace($prefix, $uri)) { | |
return false; | |
} | |
} | |
return true; | |
} | |
/** | |
* Register a namespace with the XML parser. This should be | |
* overridden by subclasses. | |
* | |
* @param string $prefix The namespace prefix to appear in XML tag | |
* names. | |
* | |
* @param string $uri The namespace URI to be used to identify the | |
* namespace in the XML. | |
* | |
* @return boolean $result True if the registration succeeded; | |
* false otherwise. | |
*/ | |
function registerNamespace($prefix, $uri) | |
{ | |
// Not implemented. | |
} | |
/** | |
* Set this parser object's XML payload. This should be | |
* overridden by subclasses. | |
* | |
* @param string $xml_string The XML string to pass to this | |
* object's XML parser. | |
* | |
* @return boolean $result True if the initialization succeeded; | |
* false otherwise. | |
*/ | |
function setXML($xml_string) | |
{ | |
// Not implemented. | |
} | |
/** | |
* Evaluate an XPath expression and return the resulting node | |
* list. This should be overridden by subclasses. | |
* | |
* @param string $xpath The XPath expression to be evaluated. | |
* | |
* @param mixed $node A node object resulting from a previous | |
* evalXPath call. This node, if specified, provides the context | |
* for the evaluation of this xpath expression. | |
* | |
* @return array $node_list An array of matching opaque node | |
* objects to be used with other methods of this parser class. | |
*/ | |
function &evalXPath($xpath, $node = null) | |
{ | |
// Not implemented. | |
} | |
/** | |
* Return the textual content of a specified node. | |
* | |
* @param mixed $node A node object from a previous call to | |
* $this->evalXPath(). | |
* | |
* @return string $content The content of this node. | |
*/ | |
function content($node) | |
{ | |
// Not implemented. | |
} | |
/** | |
* Return the attributes of a specified node. | |
* | |
* @param mixed $node A node object from a previous call to | |
* $this->evalXPath(). | |
* | |
* @return array $attrs An array mapping attribute names to | |
* values. | |
*/ | |
function attributes($node) | |
{ | |
// Not implemented. | |
} | |
} | |
/** | |
* This concrete implementation of Auth_Yadis_XMLParser implements | |
* the appropriate API for the 'domxml' extension which is typically | |
* packaged with PHP 4. This class will be used whenever the 'domxml' | |
* extension is detected. See the Auth_Yadis_XMLParser class for | |
* details on this class's methods. | |
* | |
* @package OpenID | |
*/ | |
class Auth_Yadis_domxml extends Auth_Yadis_XMLParser { | |
function Auth_Yadis_domxml() | |
{ | |
$this->xml = null; | |
$this->doc = null; | |
$this->xpath = null; | |
$this->errors = array(); | |
} | |
function setXML($xml_string) | |
{ | |
$this->xml = $xml_string; | |
$this->doc = @domxml_open_mem($xml_string, DOMXML_LOAD_PARSING, | |
$this->errors); | |
if (!$this->doc) { | |
return false; | |
} | |
$this->xpath = $this->doc->xpath_new_context(); | |
return true; | |
} | |
function registerNamespace($prefix, $uri) | |
{ | |
return xpath_register_ns($this->xpath, $prefix, $uri); | |
} | |
function &evalXPath($xpath, $node = null) | |
{ | |
if ($node) { | |
$result = @$this->xpath->xpath_eval($xpath, $node); | |
} else { | |
$result = @$this->xpath->xpath_eval($xpath); | |
} | |
if (!$result) { | |
$n = array(); | |
return $n; | |
} | |
if (!$result->nodeset) { | |
$n = array(); | |
return $n; | |
} | |
return $result->nodeset; | |
} | |
function content($node) | |
{ | |
if ($node) { | |
return $node->get_content(); | |
} | |
} | |
function attributes($node) | |
{ | |
if ($node) { | |
$arr = $node->attributes(); | |
$result = array(); | |
if ($arr) { | |
foreach ($arr as $attrnode) { | |
$result[$attrnode->name] = $attrnode->value; | |
} | |
} | |
return $result; | |
} | |
} | |
} | |
/** | |
* This concrete implementation of Auth_Yadis_XMLParser implements | |
* the appropriate API for the 'dom' extension which is typically | |
* packaged with PHP 5. This class will be used whenever the 'dom' | |
* extension is detected. See the Auth_Yadis_XMLParser class for | |
* details on this class's methods. | |
* | |
* @package OpenID | |
*/ | |
class Auth_Yadis_dom extends Auth_Yadis_XMLParser { | |
function Auth_Yadis_dom() | |
{ | |
$this->xml = null; | |
$this->doc = null; | |
$this->xpath = null; | |
$this->errors = array(); | |
} | |
function setXML($xml_string) | |
{ | |
$this->xml = $xml_string; | |
$this->doc = new DOMDocument; | |
if (!$this->doc) { | |
return false; | |
} | |
if (!@$this->doc->loadXML($xml_string)) { | |
return false; | |
} | |
$this->xpath = new DOMXPath($this->doc); | |
if ($this->xpath) { | |
return true; | |
} else { | |
return false; | |
} | |
} | |
function registerNamespace($prefix, $uri) | |
{ | |
return $this->xpath->registerNamespace($prefix, $uri); | |
} | |
function &evalXPath($xpath, $node = null) | |
{ | |
if ($node) { | |
$result = @$this->xpath->query($xpath, $node); | |
} else { | |
$result = @$this->xpath->query($xpath); | |
} | |
$n = array(); | |
if (!$result) { | |
return $n; | |
} | |
for ($i = 0; $i < $result->length; $i++) { | |
$n[] = $result->item($i); | |
} | |
return $n; | |
} | |
function content($node) | |
{ | |
if ($node) { | |
return $node->textContent; | |
} | |
} | |
function attributes($node) | |
{ | |
if ($node) { | |
$arr = $node->attributes; | |
$result = array(); | |
if ($arr) { | |
for ($i = 0; $i < $arr->length; $i++) { | |
$node = $arr->item($i); | |
$result[$node->nodeName] = $node->nodeValue; | |
} | |
} | |
return $result; | |
} | |
} | |
} | |
global $__Auth_Yadis_defaultParser; | |
$__Auth_Yadis_defaultParser = null; | |
/** | |
* Set a default parser to override the extension-driven selection of | |
* available parser classes. This is helpful in a test environment or | |
* one in which multiple parsers can be used but one is more | |
* desirable. | |
* | |
* @param Auth_Yadis_XMLParser $parser An instance of a | |
* Auth_Yadis_XMLParser subclass. | |
*/ | |
function Auth_Yadis_setDefaultParser($parser) | |
{ | |
global $__Auth_Yadis_defaultParser; | |
$__Auth_Yadis_defaultParser = $parser; | |
} | |
function Auth_Yadis_getSupportedExtensions() | |
{ | |
return array('dom' => 'Auth_Yadis_dom', | |
'domxml' => 'Auth_Yadis_domxml'); | |
} | |
/** | |
* Returns an instance of a Auth_Yadis_XMLParser subclass based on | |
* the availability of PHP extensions for XML parsing. If | |
* Auth_Yadis_setDefaultParser has been called, the parser used in | |
* that call will be returned instead. | |
*/ | |
function Auth_Yadis_getXMLParser() | |
{ | |
global $__Auth_Yadis_defaultParser; | |
if (isset($__Auth_Yadis_defaultParser)) { | |
return $__Auth_Yadis_defaultParser; | |
} | |
foreach(Auth_Yadis_getSupportedExtensions() as $extension => $classname) | |
{ | |
if (extension_loaded($extension)) | |
{ | |
$p = new $classname(); | |
Auth_Yadis_setDefaultParser($p); | |
return $p; | |
} | |
} | |
return false; | |
} | |
<?php | <?php |
/** | /** |
* This module contains the XRDS parsing code. | * This module contains the XRDS parsing code. |
* | * |
* PHP versions 4 and 5 | * PHP versions 4 and 5 |
* | * |
* LICENSE: See the COPYING file included in this distribution. | * LICENSE: See the COPYING file included in this distribution. |
* | * |
* @package OpenID | * @package OpenID |
* @author JanRain, Inc. <openid@janrain.com> | * @author JanRain, Inc. <openid@janrain.com> |
* @copyright 2005-2008 Janrain, Inc. | * @copyright 2005-2008 Janrain, Inc. |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache |
*/ | */ |
/** | /** |
* Require the XPath implementation. | * Require the XPath implementation. |
*/ | */ |
require_once 'Auth/Yadis/XML.php'; | require_once 'Auth/Yadis/XML.php'; |
/** | /** |
* This match mode means a given service must match ALL filters passed | * This match mode means a given service must match ALL filters passed |
* to the Auth_Yadis_XRDS::services() call. | * to the Auth_Yadis_XRDS::services() call. |
*/ | */ |
define('SERVICES_YADIS_MATCH_ALL', 101); | define('SERVICES_YADIS_MATCH_ALL', 101); |
/** | /** |
* This match mode means a given service must match ANY filters (at | * This match mode means a given service must match ANY filters (at |
* least one) passed to the Auth_Yadis_XRDS::services() call. | * least one) passed to the Auth_Yadis_XRDS::services() call. |
*/ | */ |
define('SERVICES_YADIS_MATCH_ANY', 102); | define('SERVICES_YADIS_MATCH_ANY', 102); |
/** | /** |
* The priority value used for service elements with no priority | * The priority value used for service elements with no priority |
* specified. | * specified. |
*/ | */ |
define('SERVICES_YADIS_MAX_PRIORITY', pow(2, 30)); | define('SERVICES_YADIS_MAX_PRIORITY', pow(2, 30)); |
/** | /** |
* XRD XML namespace | * XRD XML namespace |
*/ | */ |
define('Auth_Yadis_XMLNS_XRD_2_0', 'xri://$xrd*($v*2.0)'); | define('Auth_Yadis_XMLNS_XRD_2_0', 'xri://$xrd*($v*2.0)'); |
/** | /** |
* XRDS XML namespace | * XRDS XML namespace |
*/ | */ |
define('Auth_Yadis_XMLNS_XRDS', 'xri://$xrds'); | define('Auth_Yadis_XMLNS_XRDS', 'xri://$xrds'); |
function Auth_Yadis_getNSMap() | function Auth_Yadis_getNSMap() |
{ | { |
return array('xrds' => Auth_Yadis_XMLNS_XRDS, | return array('xrds' => Auth_Yadis_XMLNS_XRDS, |
'xrd' => Auth_Yadis_XMLNS_XRD_2_0); | 'xrd' => Auth_Yadis_XMLNS_XRD_2_0); |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function Auth_Yadis_array_scramble($arr) | function Auth_Yadis_array_scramble($arr) |
{ | { |
$result = array(); | $result = array(); |
while (count($arr)) { | while (count($arr)) { |
$index = array_rand($arr, 1); | $index = array_rand($arr, 1); |
$result[] = $arr[$index]; | $result[] = $arr[$index]; |
unset($arr[$index]); | unset($arr[$index]); |
} | } |
return $result; | return $result; |
} | } |
/** | /** |
* This class represents a <Service> element in an XRDS document. | * This class represents a <Service> element in an XRDS document. |
* Objects of this type are returned by | * Objects of this type are returned by |
* Auth_Yadis_XRDS::services() and | * Auth_Yadis_XRDS::services() and |
* Auth_Yadis_Yadis::services(). Each object corresponds directly | * Auth_Yadis_Yadis::services(). Each object corresponds directly |
* to a <Service> element in the XRDS and supplies a | * to a <Service> element in the XRDS and supplies a |
* getElements($name) method which you should use to inspect the | * getElements($name) method which you should use to inspect the |
* element's contents. See {@link Auth_Yadis_Yadis} for more | * element's contents. See {@link Auth_Yadis_Yadis} for more |
* information on the role this class plays in Yadis discovery. | * information on the role this class plays in Yadis discovery. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_Service { | class Auth_Yadis_Service { |
/** | /** |
* Creates an empty service object. | * Creates an empty service object. |
*/ | */ |
function Auth_Yadis_Service() | function Auth_Yadis_Service() |
{ | { |
$this->element = null; | $this->element = null; |
$this->parser = null; | $this->parser = null; |
} | } |
/** | /** |
* Return the URIs in the "Type" elements, if any, of this Service | * Return the URIs in the "Type" elements, if any, of this Service |
* element. | * element. |
* | * |
* @return array $type_uris An array of Type URI strings. | * @return array $type_uris An array of Type URI strings. |
*/ | */ |
function getTypes() | function getTypes() |
{ | { |
$t = array(); | $t = array(); |
foreach ($this->getElements('xrd:Type') as $elem) { | foreach ($this->getElements('xrd:Type') as $elem) { |
$c = $this->parser->content($elem); | $c = $this->parser->content($elem); |
if ($c) { | if ($c) { |
$t[] = $c; | $t[] = $c; |
} | } |
} | } |
return $t; | return $t; |
} | } |
function matchTypes($type_uris) | function matchTypes($type_uris) |
{ | { |
$result = array(); | $result = array(); |
foreach ($this->getTypes() as $typ) { | foreach ($this->getTypes() as $typ) { |
if (in_array($typ, $type_uris)) { | if (in_array($typ, $type_uris)) { |
$result[] = $typ; | $result[] = $typ; |
} | } |
} | } |
return $result; | return $result; |
} | } |
/** | /** |
* Return the URIs in the "URI" elements, if any, of this Service | * Return the URIs in the "URI" elements, if any, of this Service |
* element. The URIs are returned sorted in priority order. | * element. The URIs are returned sorted in priority order. |
* | * |
* @return array $uris An array of URI strings. | * @return array $uris An array of URI strings. |
*/ | */ |
function getURIs() | function getURIs() |
{ | { |
$uris = array(); | $uris = array(); |
$last = array(); | $last = array(); |
foreach ($this->getElements('xrd:URI') as $elem) { | foreach ($this->getElements('xrd:URI') as $elem) { |
$uri_string = $this->parser->content($elem); | $uri_string = $this->parser->content($elem); |
$attrs = $this->parser->attributes($elem); | $attrs = $this->parser->attributes($elem); |
if ($attrs && | if ($attrs && |
array_key_exists('priority', $attrs)) { | array_key_exists('priority', $attrs)) { |
$priority = intval($attrs['priority']); | $priority = intval($attrs['priority']); |
if (!array_key_exists($priority, $uris)) { | if (!array_key_exists($priority, $uris)) { |
$uris[$priority] = array(); | $uris[$priority] = array(); |
} | } |
$uris[$priority][] = $uri_string; | $uris[$priority][] = $uri_string; |
} else { | } else { |
$last[] = $uri_string; | $last[] = $uri_string; |
} | } |
} | } |
$keys = array_keys($uris); | $keys = array_keys($uris); |
sort($keys); | sort($keys); |
// Rebuild array of URIs. | // Rebuild array of URIs. |
$result = array(); | $result = array(); |
foreach ($keys as $k) { | foreach ($keys as $k) { |
$new_uris = Auth_Yadis_array_scramble($uris[$k]); | $new_uris = Auth_Yadis_array_scramble($uris[$k]); |
$result = array_merge($result, $new_uris); | $result = array_merge($result, $new_uris); |
} | } |
$result = array_merge($result, | $result = array_merge($result, |
Auth_Yadis_array_scramble($last)); | Auth_Yadis_array_scramble($last)); |
return $result; | return $result; |
} | } |
/** | /** |
* Returns the "priority" attribute value of this <Service> | * Returns the "priority" attribute value of this <Service> |
* element, if the attribute is present. Returns null if not. | * element, if the attribute is present. Returns null if not. |
* | * |
* @return mixed $result Null or integer, depending on whether | * @return mixed $result Null or integer, depending on whether |
* this Service element has a 'priority' attribute. | * this Service element has a 'priority' attribute. |
*/ | */ |
function getPriority() | function getPriority() |
{ | { |
$attributes = $this->parser->attributes($this->element); | $attributes = $this->parser->attributes($this->element); |
if (array_key_exists('priority', $attributes)) { | if (array_key_exists('priority', $attributes)) { |
return intval($attributes['priority']); | return intval($attributes['priority']); |
} | } |
return null; | return null; |
} | } |
/** | /** |
* Used to get XML elements from this object's <Service> element. | * Used to get XML elements from this object's <Service> element. |
* | * |
* This is what you should use to get all custom information out | * This is what you should use to get all custom information out |
* of this element. This is used by service filter functions to | * of this element. This is used by service filter functions to |
* determine whether a service element contains specific tags, | * determine whether a service element contains specific tags, |
* etc. NOTE: this only considers elements which are direct | * etc. NOTE: this only considers elements which are direct |
* children of the <Service> element for this object. | * children of the <Service> element for this object. |
* | * |
* @param string $name The name of the element to look for | * @param string $name The name of the element to look for |
* @return array $list An array of elements with the specified | * @return array $list An array of elements with the specified |
* name which are direct children of the <Service> element. The | * name which are direct children of the <Service> element. The |
* nodes returned by this function can be passed to $this->parser | * nodes returned by this function can be passed to $this->parser |
* methods (see {@link Auth_Yadis_XMLParser}). | * methods (see {@link Auth_Yadis_XMLParser}). |
*/ | */ |
function getElements($name) | function getElements($name) |
{ | { |
return $this->parser->evalXPath($name, $this->element); | return $this->parser->evalXPath($name, $this->element); |
} | } |
} | } |
/* | /* |
* Return the expiration date of this XRD element, or None if no | * Return the expiration date of this XRD element, or None if no |
* expiration was specified. | * expiration was specified. |
* | * |
* @param $default The value to use as the expiration if no expiration | * @param $default The value to use as the expiration if no expiration |
* was specified in the XRD. | * was specified in the XRD. |
*/ | */ |
function Auth_Yadis_getXRDExpiration($xrd_element, $default=null) | function Auth_Yadis_getXRDExpiration($xrd_element, $default=null) |
{ | { |
$expires_element = $xrd_element->$parser->evalXPath('/xrd:Expires'); | $expires_element = $xrd_element->$parser->evalXPath('/xrd:Expires'); |
if ($expires_element === null) { | if ($expires_element === null) { |
return $default; | return $default; |
} else { | } else { |
$expires_string = $expires_element->text; | $expires_string = $expires_element->text; |
// Will raise ValueError if the string is not the expected | // Will raise ValueError if the string is not the expected |
// format | // format |
$t = strptime($expires_string, "%Y-%m-%dT%H:%M:%SZ"); | $t = strptime($expires_string, "%Y-%m-%dT%H:%M:%SZ"); |
if ($t === false) { | if ($t === false) { |
return false; | return false; |
} | } |
// [int $hour [, int $minute [, int $second [, | // [int $hour [, int $minute [, int $second [, |
// int $month [, int $day [, int $year ]]]]]] | // int $month [, int $day [, int $year ]]]]]] |
return mktime($t['tm_hour'], $t['tm_min'], $t['tm_sec'], | return mktime($t['tm_hour'], $t['tm_min'], $t['tm_sec'], |
$t['tm_mon'], $t['tm_day'], $t['tm_year']); | $t['tm_mon'], $t['tm_day'], $t['tm_year']); |
} | } |
} | } |
/** | /** |
* This class performs parsing of XRDS documents. | * This class performs parsing of XRDS documents. |
* | * |
* You should not instantiate this class directly; rather, call | * You should not instantiate this class directly; rather, call |
* parseXRDS statically: | * parseXRDS statically: |
* | * |
* <pre> $xrds = Auth_Yadis_XRDS::parseXRDS($xml_string);</pre> | * <pre> $xrds = Auth_Yadis_XRDS::parseXRDS($xml_string);</pre> |
* | * |
* If the XRDS can be parsed and is valid, an instance of | * If the XRDS can be parsed and is valid, an instance of |
* Auth_Yadis_XRDS will be returned. Otherwise, null will be | * Auth_Yadis_XRDS will be returned. Otherwise, null will be |
* returned. This class is used by the Auth_Yadis_Yadis::discover | * returned. This class is used by the Auth_Yadis_Yadis::discover |
* method. | * method. |
* | * |
* @package OpenID | * @package OpenID |
*/ | */ |
class Auth_Yadis_XRDS { | class Auth_Yadis_XRDS { |
/** | /** |
* Instantiate a Auth_Yadis_XRDS object. Requires an XPath | * Instantiate a Auth_Yadis_XRDS object. Requires an XPath |
* instance which has been used to parse a valid XRDS document. | * instance which has been used to parse a valid XRDS document. |
*/ | */ |
function Auth_Yadis_XRDS($xmlParser, $xrdNodes) | function Auth_Yadis_XRDS($xmlParser, $xrdNodes) |
{ | { |
$this->parser = $xmlParser; | $this->parser = $xmlParser; |
$this->xrdNode = $xrdNodes[count($xrdNodes) - 1]; | $this->xrdNode = $xrdNodes[count($xrdNodes) - 1]; |
$this->allXrdNodes = $xrdNodes; | $this->allXrdNodes = $xrdNodes; |
$this->serviceList = array(); | $this->serviceList = array(); |
$this->_parse(); | $this->_parse(); |
} | } |
/** | /** |
* Parse an XML string (XRDS document) and return either a | * Parse an XML string (XRDS document) and return either a |
* Auth_Yadis_XRDS object or null, depending on whether the | * Auth_Yadis_XRDS object or null, depending on whether the |
* XRDS XML is valid. | * XRDS XML is valid. |
* | * |
* @param string $xml_string An XRDS XML string. | * @param string $xml_string An XRDS XML string. |
* @return mixed $xrds An instance of Auth_Yadis_XRDS or null, | * @return mixed $xrds An instance of Auth_Yadis_XRDS or null, |
* depending on the validity of $xml_string | * depending on the validity of $xml_string |
*/ | */ |
static function parseXRDS($xml_string, $extra_ns_map = null) | static function parseXRDS($xml_string, $extra_ns_map = null) |
{ | { |
$_null = null; | $_null = null; |
if (!$xml_string) { | if (!$xml_string) { |
return $_null; | return $_null; |
} | } |
$parser = Auth_Yadis_getXMLParser(); | $parser = Auth_Yadis_getXMLParser(); |
$ns_map = Auth_Yadis_getNSMap(); | $ns_map = Auth_Yadis_getNSMap(); |
if ($extra_ns_map && is_array($extra_ns_map)) { | if ($extra_ns_map && is_array($extra_ns_map)) { |
$ns_map = array_merge($ns_map, $extra_ns_map); | $ns_map = array_merge($ns_map, $extra_ns_map); |
} | } |
if (!($parser && $parser->init($xml_string, $ns_map))) { | if (!($parser && $parser->init($xml_string, $ns_map))) { |
return $_null; | return $_null; |
} | } |
// Try to get root element. | // Try to get root element. |
$root = $parser->evalXPath('/xrds:XRDS[1]'); | $root = $parser->evalXPath('/xrds:XRDS[1]'); |
if (!$root) { | if (!$root) { |
return $_null; | return $_null; |
} | } |
if (is_array($root)) { | if (is_array($root)) { |
$root = $root[0]; | $root = $root[0]; |
} | } |
$attrs = $parser->attributes($root); | $attrs = $parser->attributes($root); |
if (array_key_exists('xmlns:xrd', $attrs) && | if (array_key_exists('xmlns:xrd', $attrs) && |
$attrs['xmlns:xrd'] != Auth_Yadis_XMLNS_XRDS) { | $attrs['xmlns:xrd'] != Auth_Yadis_XMLNS_XRDS) { |
return $_null; | return $_null; |
} else if (array_key_exists('xmlns', $attrs) && | } else if (array_key_exists('xmlns', $attrs) && |
preg_match('/xri/', $attrs['xmlns']) && | preg_match('/xri/', $attrs['xmlns']) && |
$attrs['xmlns'] != Auth_Yadis_XMLNS_XRD_2_0) { | $attrs['xmlns'] != Auth_Yadis_XMLNS_XRD_2_0) { |
return $_null; | return $_null; |
} | } |
// Get the last XRD node. | // Get the last XRD node. |
$xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD'); | $xrd_nodes = $parser->evalXPath('/xrds:XRDS[1]/xrd:XRD'); |
if (!$xrd_nodes) { | if (!$xrd_nodes) { |
return $_null; | return $_null; |
} | } |
$xrds = new Auth_Yadis_XRDS($parser, $xrd_nodes); | $xrds = new Auth_Yadis_XRDS($parser, $xrd_nodes); |
return $xrds; | return $xrds; |
} | } |
/** | /** |
* @access private | * @access private |
*/ | */ |
function _addService($priority, $service) | function _addService($priority, $service) |
{ | { |
$priority = intval($priority); | $priority = intval($priority); |
if (!array_key_exists($priority, $this->serviceList)) { | if (!array_key_exists($priority, $this->serviceList)) { |
$this->serviceList[$priority] = array(); | $this->serviceList[$priority] = array(); |
} | } |
$this->serviceList[$priority][] = $service; | $this->serviceList[$priority][] = $service; |
} | } |
/** | /** |
* Creates the service list using nodes from the XRDS XML | * Creates the service list using nodes from the XRDS XML |
* document. | * document. |
* | * |
* @access private | * @access private |
*/ | */ |
function _parse() | function _parse() |
{ | { |
$this->serviceList = array(); | $this->serviceList = array(); |
$services = $this->parser->evalXPath('xrd:Service', $this->xrdNode); | $services = $this->parser->evalXPath('xrd:Service', $this->xrdNode); |
foreach ($services as $node) { | foreach ($services as $node) { |
$s = new Auth_Yadis_Service(); | $s = new Auth_Yadis_Service(); |
$s->element = $node; | $s->element = $node; |
$s->parser = $this->parser; | $s->parser = $this->parser; |
$priority = $s->getPriority(); | $priority = $s->getPriority(); |
if ($priority === null) { | if ($priority === null) { |
$priority = SERVICES_YADIS_MAX_PRIORITY; | $priority = SERVICES_YADIS_MAX_PRIORITY; |
} | } |
$this->_addService($priority, $s); | $this->_addService($priority, $s); |
} | } |
} | } |
/** | /** |
* Returns a list of service objects which correspond to <Service> | * Returns a list of service objects which correspond to <Service> |
* elements in the XRDS XML document for this object. | * elements in the XRDS XML document for this object. |
* | * |
* Optionally, an array of filter callbacks may be given to limit | * Optionally, an array of filter callbacks may be given to limit |
* the list of returned service objects. Furthermore, the default | * the list of returned service objects. Furthermore, the default |
* mode is to return all service objects which match ANY of the | * mode is to return all service objects which match ANY of the |
* specified filters, but $filter_mode may be | * specified filters, but $filter_mode may be |
* SERVICES_YADIS_MATCH_ALL if you want to be sure that the | * SERVICES_YADIS_MATCH_ALL if you want to be sure that the |
* returned services match all the given filters. See {@link | * returned services match all the given filters. See {@link |
* Auth_Yadis_Yadis} for detailed usage information on filter | * Auth_Yadis_Yadis} for detailed usage information on filter |
* functions. | * functions. |
* | * |
* @param mixed $filters An array of callbacks to filter the | * @param mixed $filters An array of callbacks to filter the |
* returned services, or null if all services are to be returned. | * returned services, or null if all services are to be returned. |
* @param integer $filter_mode SERVICES_YADIS_MATCH_ALL or | * @param integer $filter_mode SERVICES_YADIS_MATCH_ALL or |
* SERVICES_YADIS_MATCH_ANY, depending on whether the returned | * SERVICES_YADIS_MATCH_ANY, depending on whether the returned |
* services should match ALL or ANY of the specified filters, | * services should match ALL or ANY of the specified filters, |
* respectively. | * respectively. |
* @return mixed $services An array of {@link | * @return mixed $services An array of {@link |
* Auth_Yadis_Service} objects if $filter_mode is a valid | * Auth_Yadis_Service} objects if $filter_mode is a valid |
* mode; null if $filter_mode is an invalid mode (i.e., not | * mode; null if $filter_mode is an invalid mode (i.e., not |
* SERVICES_YADIS_MATCH_ANY or SERVICES_YADIS_MATCH_ALL). | * SERVICES_YADIS_MATCH_ANY or SERVICES_YADIS_MATCH_ALL). |
*/ | */ |
function services($filters = null, | function services($filters = null, |
$filter_mode = SERVICES_YADIS_MATCH_ANY) | $filter_mode = SERVICES_YADIS_MATCH_ANY) |
{ | { |
$pri_keys = array_keys($this->serviceList); | $pri_keys = array_keys($this->serviceList); |
sort($pri_keys, SORT_NUMERIC); | sort($pri_keys, SORT_NUMERIC); |
// If no filters are specified, return the entire service | // If no filters are specified, return the entire service |
// list, ordered by priority. | // list, ordered by priority. |
if (!$filters || | if (!$filters || |
(!is_array($filters))) { | (!is_array($filters))) { |
$result = array(); | $result = array(); |
foreach ($pri_keys as $pri) { | foreach ($pri_keys as $pri) { |
$result = array_merge($result, $this->serviceList[$pri]); | $result = array_merge($result, $this->serviceList[$pri]); |
} | } |
return $result; | return $result; |
} | } |
// If a bad filter mode is specified, return null. | // If a bad filter mode is specified, return null. |
if (!in_array($filter_mode, array(SERVICES_YADIS_MATCH_ANY, | if (!in_array($filter_mode, array(SERVICES_YADIS_MATCH_ANY, |
SERVICES_YADIS_MATCH_ALL))) { | SERVICES_YADIS_MATCH_ALL))) { |
return null; | return null; |
} | } |
// Otherwise, use the callbacks in the filter list to | // Otherwise, use the callbacks in the filter list to |
// determine which services are returned. | // determine which services are returned. |
$filtered = array(); | $filtered = array(); |
foreach ($pri_keys as $priority_value) { | foreach ($pri_keys as $priority_value) { |
$service_obj_list = $this->serviceList[$priority_value]; | $service_obj_list = $this->serviceList[$priority_value]; |
foreach ($service_obj_list as $service) { | foreach ($service_obj_list as $service) { |
$matches = 0; | $matches = 0; |
foreach ($filters as $filter) { | foreach ($filters as $filter) { |
if (call_user_func_array($filter, array(&$service))) { | if (call_user_func_array($filter, array($service))) { |
$matches++; | $matches++; |
if ($filter_mode == SERVICES_YADIS_MATCH_ANY) { | if ($filter_mode == SERVICES_YADIS_MATCH_ANY) { |
$pri = $service->getPriority(); | $pri = $service->getPriority(); |
if ($pri === null) { | if ($pri === null) { |
$pri = SERVICES_YADIS_MAX_PRIORITY; | $pri = SERVICES_YADIS_MAX_PRIORITY; |
} | } |
if (!array_key_exists($pri, $filtered)) { | if (!array_key_exists($pri, $filtered)) { |
$filtered[$pri] = array(); | $filtered[$pri] = array(); |
} | } |
$filtered[$pri][] = $service; | $filtered[$pri][] = $service; |
break; | break; |
} | } |
} | } |
} | } |
if (($filter_mode == SERVICES_YADIS_MATCH_ALL) && | if (($filter_mode == SERVICES_YADIS_MATCH_ALL) && |
($matches == count($filters))) { | ($matches == count($filters))) { |
$pri = $service->getPriority(); | $pri = $service->getPriority(); |
if ($pri === null) { | if ($pri === null) { |
$pri = SERVICES_YADIS_MAX_PRIORITY; | $pri = SERVICES_YADIS_MAX_PRIORITY; |
} | } |
if (!array_key_exists($pri, $filtered)) { | if (!array_key_exists($pri, $filtered)) { |
$filtered[$pri] = array(); | $filtered[$pri] = array(); |
} | } |
$filtered[$pri][] = $service; | $filtered[$pri][] = $service; |
} | } |
} | } |
} | } |
$pri_keys = array_keys($filtered); | $pri_keys = array_keys($filtered); |
sort($pri_keys, SORT_NUMERIC); | sort($pri_keys, SORT_NUMERIC); |
$result = array(); | $result = array(); |
foreach ($pri_keys as $pri) { | foreach ($pri_keys as $pri) { |
$result = array_merge($result, $filtered[$pri]); | $result = array_merge($result, $filtered[$pri]); |
} | } |
return $result; | return $result; |
} | } |
} | } |
<?php | |
/** | |
* Routines for XRI resolution. | |
* | |
* @package OpenID | |
* @author JanRain, Inc. <openid@janrain.com> | |
* @copyright 2005-2008 Janrain, Inc. | |
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache | |
*/ | |
require_once 'Auth/Yadis/Misc.php'; | |
require_once 'Auth/Yadis/Yadis.php'; | |
require_once 'Auth/OpenID.php'; | |
function Auth_Yadis_getDefaultProxy() | |
{ | |
return 'http://xri.net/'; | |
} | |
function Auth_Yadis_getXRIAuthorities() | |
{ | |
return array('!', '=', '@', '+', '$', '('); | |
} | |
function Auth_Yadis_getEscapeRE() | |
{ | |
$parts = array(); | |
foreach (array_merge(Auth_Yadis_getUCSChars(), | |
Auth_Yadis_getIPrivateChars()) as $pair) { | |
list($m, $n) = $pair; | |
$parts[] = sprintf("%s-%s", chr($m), chr($n)); | |
} | |
return sprintf('/[%s]/', implode('', $parts)); | |
} | |
function Auth_Yadis_getXrefRE() | |
{ | |
return '/\((.*?)\)/'; | |
} | |
function Auth_Yadis_identifierScheme($identifier) | |
{ | |
if (Auth_Yadis_startswith($identifier, 'xri://') || | |
($identifier && | |
in_array($identifier[0], Auth_Yadis_getXRIAuthorities()))) { | |
return "XRI"; | |
} else { | |
return "URI"; | |
} | |
} | |
function Auth_Yadis_toIRINormal($xri) | |
{ | |
if (!Auth_Yadis_startswith($xri, 'xri://')) { | |
$xri = 'xri://' . $xri; | |
} | |
return Auth_Yadis_escapeForIRI($xri); | |
} | |
function _escape_xref($xref_match) | |
{ | |
$xref = $xref_match[0]; | |
$xref = str_replace('/', '%2F', $xref); | |
$xref = str_replace('?', '%3F', $xref); | |
$xref = str_replace('#', '%23', $xref); | |
return $xref; | |
} | |
function Auth_Yadis_escapeForIRI($xri) | |
{ | |
$xri = str_replace('%', '%25', $xri); | |
$xri = preg_replace_callback(Auth_Yadis_getXrefRE(), | |
'_escape_xref', $xri); | |
return $xri; | |
} | |
function Auth_Yadis_toURINormal($xri) | |
{ | |
return Auth_Yadis_iriToURI(Auth_Yadis_toIRINormal($xri)); | |
} | |
function Auth_Yadis_iriToURI($iri) | |
{ | |
if (1) { | |
return $iri; | |
} else { | |
// According to RFC 3987, section 3.1, "Mapping of IRIs to URIs" | |
return preg_replace_callback(Auth_Yadis_getEscapeRE(), | |
'Auth_Yadis_pct_escape_unicode', $iri); | |
} | |
} | |
function Auth_Yadis_XRIAppendArgs($url, $args) | |
{ | |
// Append some arguments to an HTTP query. Yes, this is just like | |
// OpenID's appendArgs, but with special seasoning for XRI | |
// queries. | |
if (count($args) == 0) { | |
return $url; | |
} | < |