16 | * @package plist
17 | */
18 | class PListException extends \Exception {
19 |
20 | }
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/sample.xml.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Year Of Birth
6 | 1965
7 |
8 | Date Of Graduation
9 | 2004-06-22T19:23:43Z
10 |
11 | Pets Names
12 |
13 |
14 | Picture
15 | PEKBpYGlmYFCPA==
16 |
17 | City Of Birth
18 | Springfield
19 |
20 | Name
21 | John Doe
22 |
23 | Kids Names
24 |
25 | John
26 | Kyra
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-read-01.php:
--------------------------------------------------------------------------------
1 | ';
31 | var_dump( $plist->toArray() );
32 | echo '';
33 |
34 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-read-03.php:
--------------------------------------------------------------------------------
1 | ';
31 | var_dump( $plist->toArray() );
32 | echo '';
33 |
34 | $plist->saveBinary( __DIR__.'/sample.binary.plist' );
35 |
36 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rodneyrehm/plist",
3 | "description": "Library for reading and writing Apple's CFPropertyList (plist) files in XML as well as binary format.",
4 | "keywords": ["plist"],
5 | "type": "library",
6 | "homepage": "https://github.com/rodneyrehm/CFPropertyList",
7 | "license": "MIT",
8 | "require": {
9 | "php": ">=5.3"
10 | },
11 | "authors": [
12 | {
13 | "name": "Christian Kruse",
14 | "email": "cjk@wwwtech.de"
15 | },
16 | {
17 | "name": "Rodney Rehm",
18 | "email": "mail+github@rodneyrehm.de"
19 | }
20 | ],
21 | "support": {
22 | "issues": "https://github.com/rodneyrehm/CFPropertyList/issues",
23 | "source": "https://github.com/rodneyrehm/CFPropertyList"
24 | },
25 | "autoload": {
26 | "psr-0": {
27 | "CFPropertyList":"classes\/"
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-modify-01.php:
--------------------------------------------------------------------------------
1 | getValue(true) as $key => $value )
25 | {
26 | if( $key == "City Of Birth" )
27 | {
28 | $value->setValue( 'Mars' );
29 | }
30 |
31 | if( $value instanceof \Iterator )
32 | {
33 | // The value is a CFDictionary or CFArray, you may continue down the tree
34 | }
35 | }
36 |
37 |
38 | // save data
39 | $plist->save( __DIR__.'/modified.plist', CFPropertyList::FORMAT_XML );
40 |
41 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-read-02.php:
--------------------------------------------------------------------------------
1 | ';
31 | var_dump( $plist->toArray() );
32 | echo '';
33 |
34 | $plist->saveBinary( __DIR__.'/sample.binary.plist' );
35 |
36 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-read-05.php:
--------------------------------------------------------------------------------
1 | parse()
23 | */
24 | $content = file_get_contents(__DIR__.'/sample.binary.plist');
25 | $plist = new CFPropertyList();
26 | $plist->parse($content);
27 |
28 | /*
29 | * retrieve the array structure of sample.plist and dump to stdout
30 | */
31 |
32 | echo '';
33 | var_dump( $plist->toArray() );
34 | echo '
';
35 |
36 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-read-04.php:
--------------------------------------------------------------------------------
1 | parseBinary($content);
27 |
28 | /*
29 | * retrieve the array structure of sample.plist and dump to stdout
30 | */
31 |
32 | echo '';
33 | var_dump( $plist->toArray() );
34 | echo '
';
35 |
36 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2009 Christian Kruse, Rodney Rehm
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/src/scripts/vendor/composer/autoload_real.php:
--------------------------------------------------------------------------------
1 | $path) {
28 | $loader->set($namespace, $path);
29 | }
30 |
31 | $map = require __DIR__ . '/autoload_psr4.php';
32 | foreach ($map as $namespace => $path) {
33 | $loader->setPsr4($namespace, $path);
34 | }
35 |
36 | $classMap = require __DIR__ . '/autoload_classmap.php';
37 | if ($classMap) {
38 | $loader->addClassMap($classMap);
39 | }
40 |
41 | $loader->register(true);
42 |
43 | return $loader;
44 | }
45 | }
46 |
47 | function composerRequire3d99f8948a728a3257d99fd422135558($file)
48 | {
49 | require $file;
50 | }
51 |
--------------------------------------------------------------------------------
/src/scripts/vendor/composer/installed.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "rodneyrehm/plist",
4 | "version": "v2.0",
5 | "version_normalized": "2.0.0.0",
6 | "source": {
7 | "type": "git",
8 | "url": "https://github.com/rodneyrehm/CFPropertyList.git",
9 | "reference": "a59040c1c86188eec89de43f8827b42a0bd36028"
10 | },
11 | "dist": {
12 | "type": "zip",
13 | "url": "https://api.github.com/repos/rodneyrehm/CFPropertyList/zipball/a59040c1c86188eec89de43f8827b42a0bd36028",
14 | "reference": "a59040c1c86188eec89de43f8827b42a0bd36028",
15 | "shasum": ""
16 | },
17 | "require": {
18 | "php": ">=5.3"
19 | },
20 | "time": "2012-07-22 10:57:41",
21 | "type": "library",
22 | "installation-source": "dist",
23 | "autoload": {
24 | "psr-0": {
25 | "CFPropertyList": "classes/"
26 | }
27 | },
28 | "notification-url": "https://packagist.org/downloads/",
29 | "license": [
30 | "MIT"
31 | ],
32 | "authors": [
33 | {
34 | "name": "Christian Kruse",
35 | "email": "cjk@wwwtech.de"
36 | },
37 | {
38 | "name": "Rodney Rehm",
39 | "email": "mail+github@rodneyrehm.de"
40 | }
41 | ],
42 | "description": "Library for reading and writing Apple's CFPropertyList (plist) files in XML as well as binary format.",
43 | "homepage": "https://github.com/rodneyrehm/CFPropertyList",
44 | "keywords": [
45 | "plist"
46 | ]
47 | }
48 | ]
49 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-create-03.php:
--------------------------------------------------------------------------------
1 | 1965,
33 | // Note: dates cannot be guessed, it thus has to be specified explicitly
34 | 'Date Of Graduation' => new CFDate( gmmktime( 19, 23, 43, 06, 22, 2004 ) ),
35 | 'Pets Names' => array(),
36 | // Note: data cannot be guessed, it thus has to be specified explicitly
37 | 'Picture' => new CFData( 'PEKBpYGlmYFCPA==', true ),
38 | 'City Of Birth' => 'Springfield',
39 | 'Name' => 'John Doe',
40 | 'Kids Names' => array( 'John', 'Kyra' ),
41 | );
42 |
43 | $td = new CFTypeDetector();
44 | $guessedStructure = $td->toCFType( $structure );
45 | $plist->add( $guessedStructure );
46 |
47 |
48 | /*
49 | * Save PList as XML
50 | */
51 | $plist->saveXML( __DIR__.'/example-create-03.xml.plist' );
52 |
53 | /*
54 | * Save PList as Binary
55 | */
56 | $plist->saveBinary( __DIR__.'/example-create-03.binary.plist' );
57 |
58 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-create-02.php:
--------------------------------------------------------------------------------
1 | 1965,
33 | // Note: dates cannot be guessed, so this will become a CFNumber and be treated as an integer
34 | // See example-04.php for a possible workaround
35 | 'Date Of Graduation' => gmmktime( 19, 23, 43, 06, 22, 2004 ),
36 | 'Date Of Birth' => new DateTime( '1984-09-07 08:15:23', new DateTimeZone( 'Europe/Berlin' ) ),
37 | 'Pets Names' => array(),
38 | // Note: data cannot be guessed, so this will become a CFString
39 | // See example-03.php for a possible workaround
40 | 'Picture' => 'PEKBpYGlmYFCPA==',
41 | 'City Of Birth' => 'Springfield',
42 | 'Name' => 'John Doe',
43 | 'Kids Names' => array( 'John', 'Kyra' ),
44 | );
45 |
46 | $td = new CFTypeDetector();
47 | $guessedStructure = $td->toCFType( $structure );
48 | $plist->add( $guessedStructure );
49 |
50 |
51 | /*
52 | * Save PList as XML
53 | */
54 | $plist->saveXML( __DIR__.'/example-create-02.xml.plist' );
55 |
56 | /*
57 | * Save PList as Binary
58 | */
59 | $plist->saveBinary( __DIR__.'/example-create-02.binary.plist' );
60 |
61 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/tests/WriteXMLTest.php:
--------------------------------------------------------------------------------
1 | add('given-name',new CFString('John'));
25 | $names->add('surname',new CFString('Dow'));
26 |
27 | $dict->add('names',$names);
28 |
29 | $pets = new CFArray();
30 | $pets->add(new CFString('Jonny'));
31 | $pets->add(new CFString('Bello'));
32 | $dict->add('pets',$pets);
33 |
34 | $dict->add('age',new CFNumber(28));
35 | $dict->add('birth-date',new CFDate(412035803));
36 |
37 | $plist->add($dict);
38 | $plist->saveXML(WRITE_XML_DATA_FILE);
39 |
40 | $this->assertTrue(is_file(WRITE_XML_DATA_FILE));
41 |
42 | $plist->load(WRITE_XML_DATA_FILE);
43 |
44 | unlink(WRITE_XML_DATA_FILE);
45 | }
46 |
47 | public function testWriteString() {
48 | $plist = new CFPropertyList();
49 | $dict = new CFDictionary();
50 |
51 | $names = new CFDictionary();
52 | $names->add('given-name',new CFString('John'));
53 | $names->add('surname',new CFString('Dow'));
54 |
55 | $dict->add('names',$names);
56 |
57 | $pets = new CFArray();
58 | $pets->add(new CFString('Jonny'));
59 | $pets->add(new CFString('Bello'));
60 | $dict->add('pets',$pets);
61 |
62 | $dict->add('age',new CFNumber(28));
63 | $dict->add('birth-date',new CFDate(412035803));
64 |
65 | $plist->add($dict);
66 | $content = $plist->toXML();
67 |
68 | $plist->parse($content);
69 | }
70 |
71 | }
72 |
73 |
74 | # eof
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-create-01.php:
--------------------------------------------------------------------------------
1 | add( $dict = new CFDictionary() );
30 |
31 | // Year Of Birth1965
32 | $dict->add( 'Year Of Birth', new CFNumber( 1965 ) );
33 |
34 | // Date Of Graduation2004-06-22T19:23:43Z
35 | $dict->add( 'Date Of Graduation', new CFDate( gmmktime( 19, 23, 43, 06, 22, 2004 ) ) );
36 |
37 | // Pets Names
38 | $dict->add( 'Pets Names', new CFArray() );
39 |
40 | // PicturePEKBpYGlmYFCPA==
41 | // to keep it simple we insert an already base64-encoded string
42 | $dict->add( 'Picture', new CFData( 'PEKBpYGlmYFCPA==', true ) );
43 |
44 | // City Of BirthSpringfield
45 | $dict->add( 'City Of Birth', new CFString( 'Springfield' ) );
46 |
47 | // NameJohn Doe
48 | $dict->add( 'Name', new CFString( 'John Doe' ) );
49 |
50 | // Kids NamesJohnKyra
51 | $dict->add( 'Kids Names', $array = new CFArray() );
52 | $array->add( new CFString( 'John' ) );
53 | $array->add( new CFString( 'Kyra' ) );
54 |
55 |
56 | /*
57 | * Save PList as XML
58 | */
59 | $plist->saveXML( __DIR__.'/example-create-01.xml.plist' );
60 |
61 |
62 | /*
63 | * Save PList as Binary
64 | */
65 | $plist->saveBinary( __DIR__.'/example-create-01.binary.plist' );
66 |
67 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/tests/WriteBinaryTest.php:
--------------------------------------------------------------------------------
1 | add('given-name',new CFString('John'));
25 | $names->add('surname',new CFString('Dow'));
26 |
27 | $dict->add('names',$names);
28 |
29 | $pets = new CFArray();
30 | $pets->add(new CFString('Jonny'));
31 | $pets->add(new CFString('Bello'));
32 | $dict->add('pets',$pets);
33 |
34 | $dict->add('age',new CFNumber(28));
35 | $dict->add('birth-date',new CFDate(412035803));
36 |
37 | $plist->add($dict);
38 | $plist->saveBinary(WRITE_BINARY_DATA_FILE);
39 |
40 | $this->assertTrue(is_file(WRITE_BINARY_DATA_FILE));
41 | $this->assertTrue(filesize(WRITE_BINARY_DATA_FILE) > 32);
42 |
43 | $plist->load(WRITE_BINARY_DATA_FILE);
44 |
45 | unlink(WRITE_BINARY_DATA_FILE);
46 | }
47 |
48 | public function testWriteString() {
49 | $plist = new CFPropertyList();
50 | $dict = new CFDictionary();
51 |
52 | $names = new CFDictionary();
53 | $names->add('given-name',new CFString('John'));
54 | $names->add('surname',new CFString('Dow'));
55 |
56 | $dict->add('names',$names);
57 |
58 | $pets = new CFArray();
59 | $pets->add(new CFString('Jonny'));
60 | $pets->add(new CFString('Bello'));
61 | $dict->add('pets',$pets);
62 |
63 | $dict->add('age',new CFNumber(28));
64 | $dict->add('birth-date',new CFDate(412035803));
65 |
66 | $plist->add($dict);
67 | $content = $plist->toBinary();
68 |
69 | $this->assertTrue(strlen($content) > 32);
70 |
71 | $plist->parse($content);
72 | }
73 |
74 | }
75 |
76 |
77 | # eof
--------------------------------------------------------------------------------
/src/scripts/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "91e51b0843c73951c56525e427e2e52e",
8 | "packages": [
9 | {
10 | "name": "rodneyrehm/plist",
11 | "version": "v2.0",
12 | "source": {
13 | "type": "git",
14 | "url": "https://github.com/rodneyrehm/CFPropertyList.git",
15 | "reference": "a59040c1c86188eec89de43f8827b42a0bd36028"
16 | },
17 | "dist": {
18 | "type": "zip",
19 | "url": "https://api.github.com/repos/rodneyrehm/CFPropertyList/zipball/a59040c1c86188eec89de43f8827b42a0bd36028",
20 | "reference": "a59040c1c86188eec89de43f8827b42a0bd36028",
21 | "shasum": ""
22 | },
23 | "require": {
24 | "php": ">=5.3"
25 | },
26 | "type": "library",
27 | "autoload": {
28 | "psr-0": {
29 | "CFPropertyList": "classes/"
30 | }
31 | },
32 | "notification-url": "https://packagist.org/downloads/",
33 | "license": [
34 | "MIT"
35 | ],
36 | "authors": [
37 | {
38 | "name": "Christian Kruse",
39 | "email": "cjk@wwwtech.de"
40 | },
41 | {
42 | "name": "Rodney Rehm",
43 | "email": "mail+github@rodneyrehm.de"
44 | }
45 | ],
46 | "description": "Library for reading and writing Apple's CFPropertyList (plist) files in XML as well as binary format.",
47 | "homepage": "https://github.com/rodneyrehm/CFPropertyList",
48 | "keywords": [
49 | "plist"
50 | ],
51 | "time": "2012-07-22 10:57:41"
52 | }
53 | ],
54 | "packages-dev": [
55 |
56 | ],
57 | "aliases": [
58 |
59 | ],
60 | "minimum-stability": "stable",
61 | "stability-flags": [
62 |
63 | ],
64 | "prefer-stable": false,
65 | "platform": [
66 |
67 | ],
68 | "platform-dev": [
69 |
70 | ]
71 | }
72 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/README.md:
--------------------------------------------------------------------------------
1 | # CFPropertyList
2 |
3 | The PHP implementation of Apple's PropertyList can handle XML PropertyLists as well as binary PropertyLists. It offers functionality to easily convert data between worlds, e.g. recalculating timestamps from unix epoch to apple epoch and vice versa. A feature to automagically create (guess) the plist structure from a normal PHP data structure will help you dump your data to plist in no time.
4 |
5 | Note: CFPropertylist was originally hosted on [Google Code](http://code.google.com/p/cfpropertylist/)
6 |
7 | ## Choose Your Favorite Operating System
8 |
9 | CFPropertyList does not rely on any "Apple proprietary" components, like plutil. CFPropertyList runs on any Operating System with PHP and some standard extensions installed.
10 |
11 | Although you might want to deliver data to your iPhone application, you might want to run those server side services on your standard Linux (or even Windows) environment, rather than buying an expensive Apple Server. With CFPropertyList you now have the power to provide data from your favorite Operating System.
12 |
13 | ## Requirements And Limitations
14 |
15 | * requires PHP5.3 (as of CFPropertyList 2.0)
16 | * requires either [MBString](http://php.net/mbstring) or [Iconv](http://php.net/iconv)
17 | * requires either [BC](http://php.net/bc) or [GMP](http://php.net/gmp) or [phpseclib](http://phpseclib.sourceforge.net/) (see BigIntegerBug for an explanation) - as of CFPropertyList 1.0.1
18 |
19 | ## Authors
20 |
21 | - Rodney Rehm
22 | - Christian Kruse
23 | - PSR-0 changes by Jarvis Badgley
24 |
25 | ## License
26 |
27 | CFPropertyList is published under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
28 |
29 | ## Installation
30 |
31 | Next to cloning the git repository or [downloading](https://github.com/rodneyrehm/CFPropertyList/archives/master) an archive, you can now use [PEAR](http://www.pearhub.org/projects/CFPropertyList) thanks to [pearhub](https://github.com/troelskn/pearhub).
32 |
33 | ## Related
34 |
35 | * [man(5) plist](http://developer.apple.com/documentation/Darwin/Reference/ManPages/man5/plist.5.html)
36 | * [CFBinaryPList.c](http://www.opensource.apple.com/source/CF/CF-476.15/CFBinaryPList.c)
37 | * [CFPropertyList in Ruby](http://rubyforge.org/projects/cfpropertylist/)
38 | * [CFPropertyList in Python](https://github.com/bencochran/CFPropertyList)
39 | * [plist on Wikipedia](http://en.wikipedia.org/wiki/Plist)
40 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | alfred-devdocs [](https://www.paypal.me/yannickgalatol)
2 | ==============
3 |
4 | Alfred workflow for the amazing [devdocs.io](http://devdocs.io/) documentations.
5 |
6 | # Install
7 | Use the packaged workflow [DevDocs.alfredworkflow](https://github.com/packal/repository/raw/master/com.yannickglt.alfred2.devdocs/devdocs.alfredworkflow) from packal.
8 |
9 | # How to
10 |
11 | ## Add a documentation
12 |
13 | By default, the Alfred Devdocs workflow comes without any documentation. First of all, you must add one or several docs you want to browse using the `cdoc:add` command. For example:
14 | ```
15 | cdoc:add javascript
16 | ```
17 |
18 | #### Other configuration commands
19 |
20 | - `cdoc:list`: List all docs you can add in your workflow
21 | - `cdoc:add`: Add a doc in your workflow, if you have already all docs, that command do nothing
22 | - `cdoc:remove`: Remove a doc in your workflow, if you haven't a doc in your workflow, that command do nothing
23 | - `cdoc:all`: Add all docs available to your workflow (not recommended)
24 | - `cdoc:nuke`: Remove all docs in your workflow
25 | - `cdoc:refresh`: Refresh cache for a doc (if specified) or all the added docs otherwise
26 | - `cdoc:alias`: Create an alias for a documentation
27 | - `cdoc:unalias`: Remove an existing alias of a documentation
28 |
29 | ## Find in a specific documentation
30 | Keywords exist for each documentation supported by DevDocs.
31 |
32 | 
33 |
34 | ## Completion
35 |
36 | 
37 |
38 | ## Global search
39 | Global search may be slow the first time it is called because it will download all the documentations at once.
40 |
41 | 
42 |
43 | ## Alfred preview
44 | Using the "shift" key on a function will display a preview (using quicklook) of the doc.
45 | 
46 |
47 | ## Use behind an HTTP proxy
48 | Define the `HTTP_PROXY` environment variable in Alfred as below. You can define the `HTTP_PROXY_AUTHORIZATION` as well if your proxy needs basic authentication.
49 | 
50 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/examples/example-create-04.php:
--------------------------------------------------------------------------------
1 | getMessage() );
24 | }
25 |
26 | return parent::toCFType($value);
27 | }
28 |
29 | }
30 |
31 | /*
32 | * import the array structure to create the sample.xml.plist
33 | * We make use of CFTypeDetector, which truly is not almighty!
34 | */
35 |
36 | $stack = new \SplStack();
37 | $stack[] = 1;
38 | $stack[] = 2;
39 | $stack[] = 3;
40 |
41 | $structure = array(
42 | 'NullValueTest' => null,
43 | 'IteratorTest' => $stack,
44 | 'ObjectTest' => new PListException('Just a test...'),
45 | );
46 |
47 | /*
48 | * Try default detection
49 | */
50 | try {
51 | $plist = new CFPropertyList();
52 | $td = new CFTypeDetector();
53 | $guessedStructure = $td->toCFType( $structure );
54 | $plist->add( $guessedStructure );
55 | $plist->saveXML( __DIR__.'/example-create-04.xml.plist' );
56 | $plist->saveBinary( __DIR__.'/example-create-04.binary.plist' );
57 | }
58 | catch( PListException $e ) {
59 | echo 'Normal detection: ', $e->getMessage(), "\n";
60 | }
61 |
62 | /*
63 | * Try detection by omitting exceptions
64 | */
65 | try {
66 | $plist = new CFPropertyList();
67 | $td = new CFTypeDetector( array('suppressExceptions' => true) );
68 | $guessedStructure = $td->toCFType( $structure );
69 | $plist->add( $guessedStructure );
70 | $plist->saveXML( __DIR__.'/example-create-04.xml.plist' );
71 | $plist->saveBinary( __DIR__.'/example-create-04.binary.plist' );
72 | }
73 | catch( PListException $e ) {
74 | echo 'Silent detection: ', $e->getMessage(), "\n";
75 | }
76 |
77 | /*
78 | * Try detection with an extended version of CFTypeDetector
79 | */
80 | try {
81 | $plist = new CFPropertyList();
82 | $td = new DemoDetector();
83 | $guessedStructure = $td->toCFType( $structure );
84 | $plist->add( $guessedStructure );
85 | $plist->saveXML( __DIR__.'/example-create-04.xml.plist' );
86 | $plist->saveBinary( __DIR__.'/example-create-04.binary.plist' );
87 | }
88 | catch( PListException $e ) {
89 | echo 'User defined detection: ', $e->getMessage(), "\n";
90 | }
91 |
92 | ?>
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/IOException.php:
--------------------------------------------------------------------------------
1 |
6 | * @author Christian Kruse
7 | * @package plist
8 | * @version $Id$
9 | */
10 | namespace CFPropertyList;
11 |
12 | /**
13 | * Basic Input / Output Exception
14 | * @author Rodney Rehm
15 | * @author Christian Kruse
16 | * @package plist
17 | */
18 | class IOException extends \Exception {
19 | /**
20 | * Flag telling the File could not be found
21 | */
22 | const NOT_FOUND = 1;
23 |
24 | /**
25 | * Flag telling the File is not readable
26 | */
27 | const NOT_READABLE = 2;
28 |
29 | /**
30 | * Flag telling the File is not writable
31 | */
32 | const NOT_WRITABLE = 3;
33 |
34 | /**
35 | * Flag telling there was a read error
36 | */
37 | const READ_ERROR = 4;
38 |
39 | /**
40 | * Flag telling there was a read error
41 | */
42 | const WRITE_ERROR = 5;
43 |
44 | /**
45 | * Create new IOException
46 | * @param string $path Source of the problem
47 | * @param integer $type Type of the problem
48 | */
49 | public function __construct($path, $type=null) {
50 | parent::__construct( $path, $type );
51 | }
52 |
53 | /**
54 | * Create new FileNotFound-Exception
55 | * @param string $path Source of the problem
56 | * @return IOException new FileNotFound-Exception
57 | */
58 | public static function notFound($path) {
59 | return new IOException( $path, self::NOT_FOUND );
60 | }
61 |
62 | /**
63 | * Create new FileNotReadable-Exception
64 | * @param string $path Source of the problem
65 | * @return IOException new FileNotReadable-Exception
66 | */
67 | public static function notReadable($path) {
68 | return new IOException( $path, self::NOT_READABLE );
69 | }
70 |
71 | /**
72 | * Create new FileNotWritable-Exception
73 | * @param string $path Source of the problem
74 | * @return IOException new FileNotWritable-Exception
75 | */
76 | public static function notWritable($path) {
77 | return new IOException( $path, self::NOT_WRITABLE );
78 | }
79 |
80 | /**
81 | * Create new ReadError-Exception
82 | * @param string $path Source of the problem
83 | * @return IOException new ReadError-Exception
84 | */
85 | public static function readError($path) {
86 | return new IOException( $path, self::READ_ERROR );
87 | }
88 |
89 | /**
90 | * Create new WriteError-Exception
91 | * @param string $path Source of the problem
92 | * @return IOException new WriteError-Exception
93 | */
94 | public static function writeError($path) {
95 | return new IOException( $path, self::WRITE_ERROR );
96 | }
97 | }
98 |
99 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/tests/BinaryParseTest.php:
--------------------------------------------------------------------------------
1 | toArray();
23 | $this->assertEquals(count($vals),4);
24 |
25 | $this->assertEquals($vals['names']['given-name'],'John');
26 | $this->assertEquals($vals['names']['surname'],'Dow');
27 |
28 | $this->assertEquals($vals['pets'][0],'Jonny');
29 | $this->assertEquals($vals['pets'][1],'Bello');
30 |
31 | $this->assertEquals($vals['age'],28);
32 | $this->assertEquals($vals['birth-date'],412035803);
33 | }
34 |
35 | public function testParseBinaryString() {
36 | $content = file_get_contents(TEST_BINARY_DATA_FILE);
37 |
38 | $plist = new CFPropertyList();
39 | $plist->parse($content);
40 |
41 | $vals = $plist->toArray();
42 | $this->assertEquals(count($vals),4);
43 |
44 | $this->assertEquals($vals['names']['given-name'],'John');
45 | $this->assertEquals($vals['names']['surname'],'Dow');
46 |
47 | $this->assertEquals($vals['pets'][0],'Jonny');
48 | $this->assertEquals($vals['pets'][1],'Bello');
49 |
50 | $this->assertEquals($vals['age'],28);
51 | $this->assertEquals($vals['birth-date'],412035803);
52 | }
53 |
54 | public function testParseStream() {
55 | $plist = new CFPropertyList();
56 | if(($fd = fopen(TEST_BINARY_DATA_FILE,"rb")) == NULL) {
57 | throw new IOException("Error opening test data file for reading!");
58 | }
59 |
60 | $plist->readBinaryStream($fd);
61 |
62 | $vals = $plist->toArray();
63 | $this->assertEquals(count($vals),4);
64 |
65 | $this->assertEquals($vals['names']['given-name'],'John');
66 | $this->assertEquals($vals['names']['surname'],'Dow');
67 |
68 | $this->assertEquals($vals['pets'][0],'Jonny');
69 | $this->assertEquals($vals['pets'][1],'Bello');
70 |
71 | $this->assertEquals($vals['age'],28);
72 | $this->assertEquals($vals['birth-date'],412035803);
73 | }
74 |
75 | /**
76 | * @expectedException CFPropertyList\PListException
77 | */
78 | public function testEmptyString() {
79 | $plist = new CFPropertyList();
80 | $plist->parseBinary('');
81 | }
82 |
83 | public function testInvalidString() {
84 | $catched = false;
85 |
86 | try {
87 | $plist = new CFPropertyList();
88 | $plist->parseBinary('lalala');
89 | }
90 | catch(PListException $e) {
91 | $catched = true;
92 | }
93 |
94 | if($catched == false) {
95 | $this->fail('No exception thrown for invalid string!');
96 | }
97 |
98 | $catched = false;
99 | try {
100 | $plist = new CFPropertyList();
101 | $plist->parseBinary('bplist00dfwefwefwef');
102 | }
103 | catch(PListException $e) {
104 | return;
105 | }
106 |
107 | $this->fail('No exception thrown for invalid string!');
108 | }
109 |
110 | }
111 |
112 | # eof
113 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/tests/ParseXMLTest.php:
--------------------------------------------------------------------------------
1 | toArray();
23 | $this->assertEquals(count($vals),4);
24 |
25 | $this->assertEquals($vals['names']['given-name'],'John');
26 | $this->assertEquals($vals['names']['surname'],'Dow');
27 |
28 | $this->assertEquals($vals['pets'][0],'Jonny');
29 | $this->assertEquals($vals['pets'][1],'Bello');
30 |
31 | $this->assertEquals($vals['age'],28);
32 | $this->assertEquals($vals['birth-date'],412035803);
33 | }
34 |
35 | public function testParseString() {
36 | $content = file_get_contents(TEST_XML_DATA_FILE);
37 |
38 | $plist = new CFPropertyList();
39 | $plist->parse($content);
40 |
41 | $vals = $plist->toArray();
42 | $this->assertEquals(count($vals),4);
43 |
44 | $this->assertEquals($vals['names']['given-name'],'John');
45 | $this->assertEquals($vals['names']['surname'],'Dow');
46 |
47 | $this->assertEquals($vals['pets'][0],'Jonny');
48 | $this->assertEquals($vals['pets'][1],'Bello');
49 |
50 | $this->assertEquals($vals['age'],28);
51 | $this->assertEquals($vals['birth-date'],412035803);
52 | }
53 |
54 | public function testParseStream() {
55 | $plist = new CFPropertyList();
56 | if(($fd = fopen(TEST_XML_DATA_FILE,"r")) == NULL) {
57 | throw new IOException("Error opening test data file for reading!");
58 | }
59 |
60 | $plist->loadXMLStream($fd);
61 |
62 | $vals = $plist->toArray();
63 | $this->assertEquals(count($vals),4);
64 |
65 | $this->assertEquals($vals['names']['given-name'],'John');
66 | $this->assertEquals($vals['names']['surname'],'Dow');
67 |
68 | $this->assertEquals($vals['pets'][0],'Jonny');
69 | $this->assertEquals($vals['pets'][1],'Bello');
70 |
71 | $this->assertEquals($vals['age'],28);
72 | $this->assertEquals($vals['birth-date'],412035803);
73 | }
74 |
75 | /**
76 | * @expectedException CFPropertyList\IOException
77 | */
78 | public function testEmptyString() {
79 | $plist = new CFPropertyList();
80 | $plist->parse('');
81 | }
82 |
83 | public function testInvalidString() {
84 | $catched = false;
85 |
86 | try {
87 | $plist = new CFPropertyList();
88 | $plist->parse('lalala');
89 | }
90 | catch(\DOMException $e) {
91 | $catched = true;
92 | }
93 | catch(\PHPUnit_Framework_Error $e) {
94 | $catched = true;
95 | }
96 |
97 | if($catched == false) {
98 | $this->fail('No exception thrown for invalid string!');
99 | }
100 |
101 | $catched = false;
102 | try {
103 | $plist = new CFPropertyList();
104 | $plist->parse('');
105 | }
106 | catch(PListException $e) {
107 | return;
108 | }
109 | catch(\PHPUnit_Framework_Error $e) {
110 | return;
111 | }
112 |
113 | $this->fail('No exception thrown for invalid string!');
114 | }
115 |
116 | }
117 |
118 | # eof
119 |
--------------------------------------------------------------------------------
/src/scripts/devdocs.php:
--------------------------------------------------------------------------------
1 | baseUrl = getenv('BASE_URL') ?: 'https://devdocs.io/';
22 | $this->cacheLife = (int)(getenv('CACHE_LIFE') ?: '7');
23 | $this->template = getenv('TEMPLATE') ?: '$baseUrl$documentation/$path';
24 | $this->workflows = new Workflows();
25 | $cache = $this->workflows->cache();
26 | if ($cache !== false) {
27 | self::$cacheDirectory = $cache . '/';
28 | }
29 | $this->results = [
30 | 0 => [],
31 | 1 => [],
32 | 2 => []
33 | ];
34 |
35 | $documentations = $this->getDocumentations();
36 | if (!isset($doc) || empty($doc)) {
37 | $rootPath = str_replace('/scripts', '', $this->workflows->path());
38 | $pList = (new CFPropertyList($rootPath . '/info.plist'))->toArray();
39 | foreach ($pList['connections'] as $key => $value) {
40 | if (array_key_exists($key, $documentations)) {
41 | $this->checkCache($key);
42 | $this->processDocumentation($key, $query);
43 | }
44 | }
45 | } else {
46 | $this->checkCache($doc);
47 | $this->processDocumentation($doc, $query);
48 | }
49 | $this->render();
50 | }
51 |
52 | private function getDocumentations() {
53 | $docFile = self::$cacheDirectory . 'docs.json';
54 | // Keep the docs in cache before expired
55 | if (!file_exists($docFile) || ($this->cacheLife >= 0 && filemtime($docFile) <= time() - 86400 * $this->cacheLife)) {
56 | $docContent = $this->workflows->fetch($this->baseUrl . 'docs/docs.json');
57 | file_put_contents($docFile, $docContent);
58 | } else {
59 | $docContent = file_get_contents($docFile);
60 | }
61 | $docs = json_decode($docContent);
62 | $documentations = [];
63 | foreach ($docs as $doc) {
64 | $doc->fullName = $doc->name . (!empty($doc->version) ? ' ' . $doc->version : '');
65 | $documentations[$doc->slug] = $doc;
66 | }
67 | return $documentations;
68 | }
69 |
70 | private function checkCache($documentation) {
71 | if (!file_exists(self::$cacheDirectory)) {
72 | mkdir(self::$cacheDirectory);
73 | }
74 | $docFile = self::$cacheDirectory . $documentation . '.json';
75 | error_log("Checking existence of cache at $docFile");
76 | // Keep the docs in cache before expired
77 | if (!file_exists($docFile) || ($this->cacheLife >= 0 && filemtime($docFile) <= time() - 86400 * $this->cacheLife)) {
78 | error_log("Download doc for $documentation at \"" . $this->baseUrl . 'docs/' . $documentation . '/index.json') . "\"";
79 | file_put_contents($docFile, file_get_contents($this->baseUrl . 'docs/' . $documentation . '/index.json'));
80 | }
81 | }
82 |
83 | private function processDocumentation($documentation, $query) {
84 |
85 | $query = strtolower($query);
86 | $data = json_decode(file_get_contents(self::$cacheDirectory . $documentation . '.json'));
87 | if ($data === null) {
88 | unlink(self::$cacheDirectory . $documentation . '.json');
89 | }
90 |
91 | $entries = $data->entries;
92 |
93 | $found = [];
94 | foreach ($entries as $key => $result) {
95 | $value = strtolower(trim($result->name));
96 | $description = strtolower(utf8_decode(strip_tags($result->type)));
97 |
98 | if (empty($query)) {
99 | $found[$value] = true;
100 | $result->documentation = $documentation;
101 | $this->results[0][] = $result;
102 | } else if (strpos($value, $query) === 0) {
103 | if (!isset($found[$value])) {
104 | $found[$value] = true;
105 | $result->documentation = $documentation;
106 | $this->results[0][] = $result;
107 | }
108 | } else if (strpos($value, $query) > 0) {
109 | if (!isset($found[$value])) {
110 | $found[$value] = true;
111 | $result->documentation = $documentation;
112 | $this->results[1][] = $result;
113 | }
114 | } else if (strpos($description, $query) !== false) {
115 | if (!isset($found[$value])) {
116 | $found[$value] = true;
117 | $result->documentation = $documentation;
118 | $this->results[2][] = $result;
119 | }
120 | }
121 | }
122 |
123 | if ((count($this->results[0]) === 0) && (count($this->results[1]) === 0) && (count($this->results[2]) === 0)) {
124 | $this->results[0][] = (object) [
125 | 'name' => 'No results.',
126 | 'documentation' => $documentation
127 | ];
128 | }
129 |
130 | }
131 |
132 | private function render() {
133 | foreach ($this->results as $level => $results) {
134 | foreach ($results as $result) {
135 | $title = empty($result->type) ? $result->name : "$result->name ($result->type)";
136 | $vars = array(
137 | '$baseUrl' => $this->baseUrl,
138 | '$documentation' => $result->documentation,
139 | '$docalt' => str_replace("~", "-", $result->documentation),
140 | '$name' => $result->name,
141 | '$path' => $result->path
142 | );
143 | //$url = $this->baseUrl . $result->documentation . '/' . $result->path;
144 | $url = strtr($this->template, $vars);
145 | $this->workflows->result($result->name, $url, $title, $result->path, $result->documentation . '.png', 'yes', $result->name);
146 | }
147 | }
148 | echo $this->workflows->toxml();
149 | }
150 | }
151 |
152 | $query = isset($query) ? $query : '';
153 | $documentation = isset($documentation) ? $documentation : '';
154 | new DevDocs($query, $documentation);
155 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFTypeDetector.php:
--------------------------------------------------------------------------------
1 |
7 | * @author Christian Kruse
8 | * @package plist
9 | * @subpackage plist.types
10 | * @example example-create-02.php Using {@link CFTypeDetector}
11 | * @example example-create-03.php Using {@link CFTypeDetector} with {@link CFDate} and {@link CFData}
12 | * @example example-create-04.php Using and extended {@link CFTypeDetector}
13 | */
14 |
15 | namespace CFPropertyList;
16 | use \DateTime, \Iterator;
17 |
18 | class CFTypeDetector {
19 |
20 | /**
21 | * flag stating if all arrays should automatically be converted to {@link CFDictionary}
22 | * @var boolean
23 | */
24 | protected $autoDictionary = false;
25 |
26 | /**
27 | * flag stating if exceptions should be suppressed or thrown
28 | * @var boolean
29 | */
30 | protected $suppressExceptions = false;
31 |
32 | /**
33 | * name of a method that will be used for array to object conversations
34 | * @var callable
35 | */
36 | protected $objectToArrayMethod = null;
37 |
38 | /**
39 | * flag stating if "123.23" should be converted to float (true) or preserved as string (false)
40 | * @var boolean
41 | */
42 | protected $castNumericStrings = true;
43 |
44 |
45 | /**
46 | * Create new CFTypeDetector
47 | * @param array $options Configuration for casting values [autoDictionary, suppressExceptions, objectToArrayMethod, castNumericStrings]
48 | */
49 | public function __construct(array $options=array()) {
50 | //$autoDicitionary=false,$suppressExceptions=false,$objectToArrayMethod=null
51 | foreach ($options as $key => $value) {
52 | if (property_exists($this, $key)) {
53 | $this->$key = $value;
54 | }
55 | }
56 | }
57 |
58 | /**
59 | * Determine if an array is associative or numerical.
60 | * Numerical Arrays have incrementing index-numbers that don't contain gaps.
61 | * @param array $value Array to check indexes of
62 | * @return boolean true if array is associative, false if array has numeric indexes
63 | */
64 | protected function isAssociativeArray($value) {
65 | $numericKeys = true;
66 | $i = 0;
67 | foreach($value as $key => $v) {
68 | if($i !== $key) {
69 | $numericKeys = false;
70 | break;
71 | }
72 | $i++;
73 | }
74 | return !$numericKeys;
75 | }
76 |
77 | /**
78 | * Get the default value
79 | * @return CFType the default value to return if no suitable type could be determined
80 | */
81 | protected function defaultValue() {
82 | return new CFString();
83 | }
84 |
85 | /**
86 | * Create CFType-structure by guessing the data-types.
87 | * {@link CFArray}, {@link CFDictionary}, {@link CFBoolean}, {@link CFNumber} and {@link CFString} can be created, {@link CFDate} and {@link CFData} cannot.
88 | *
Note:Distinguishing between {@link CFArray} and {@link CFDictionary} is done by examining the keys.
89 | * Keys must be strictly incrementing integers to evaluate to a {@link CFArray}.
90 | * Since PHP does not offer a function to test for associative arrays,
91 | * this test causes the input array to be walked twice and thus work rather slow on large collections.
92 | * If you work with large arrays and can live with all arrays evaluating to {@link CFDictionary},
93 | * feel free to set the appropriate flag.
94 | *
Note: If $value is an instance of CFType it is simply returned.
95 | *
Note: If $value is neither a CFType, array, numeric, boolean nor string, it is omitted.
96 | * @param mixed $value Value to convert to CFType
97 | * @param boolean $autoDictionary if true {@link CFArray}-detection is bypassed and arrays will be returned as {@link CFDictionary}.
98 | * @return CFType CFType based on guessed type
99 | * @uses isAssociativeArray() to check if an array only has numeric indexes
100 | */
101 | public function toCFType($value) {
102 | switch(true) {
103 | case $value instanceof CFType:
104 | return $value;
105 | break;
106 |
107 | case is_object($value):
108 | // DateTime should be CFDate
109 | if(class_exists( 'DateTime' ) && $value instanceof DateTime){
110 | return new CFDate($value->getTimestamp());
111 | }
112 |
113 | // convert possible objects to arrays, arrays will be arrays
114 | if($this->objectToArrayMethod && is_callable(array($value, $this->objectToArrayMethod))){
115 | $value = call_user_func( array( $value, $this->objectToArrayMethod ) );
116 | }
117 |
118 | if(!is_array($value)){
119 | if($this->suppressExceptions)
120 | return $this->defaultValue();
121 |
122 | throw new PListException('Could not determine CFType for object of type '. get_class($value));
123 | }
124 | /* break; omitted */
125 |
126 | case $value instanceof Iterator:
127 | case is_array($value):
128 | // test if $value is simple or associative array
129 | if(!$this->autoDictionary) {
130 | if(!$this->isAssociativeArray($value)) {
131 | $t = new CFArray();
132 | foreach($value as $v) $t->add($this->toCFType($v));
133 | return $t;
134 | }
135 | }
136 |
137 | $t = new CFDictionary();
138 | foreach($value as $k => $v) $t->add($k, $this->toCFType($v));
139 |
140 | return $t;
141 | break;
142 |
143 | case is_bool($value):
144 | return new CFBoolean($value);
145 | break;
146 |
147 | case is_null($value):
148 | return new CFString();
149 | break;
150 |
151 | case is_resource($value):
152 | if ($this->suppressExceptions) {
153 | return $this->defaultValue();
154 | }
155 |
156 | throw new PListException('Could not determine CFType for resource of type '. get_resource_type($value));
157 | break;
158 |
159 | case is_numeric($value):
160 | if (!$this->castNumericStrings && is_string($value)) {
161 | return new CFString($value);
162 | }
163 |
164 | return new CFNumber($value);
165 | break;
166 |
167 | case is_string($value):
168 | return new CFString($value);
169 | break;
170 |
171 | default:
172 | if ($this->suppressExceptions) {
173 | return $this->defaultValue();
174 | }
175 |
176 | throw new PListException('Could not determine CFType for '. gettype($value));
177 | break;
178 | }
179 | }
180 |
181 | }
182 |
183 |
184 |
--------------------------------------------------------------------------------
/src/scripts/vendor/composer/ClassLoader.php:
--------------------------------------------------------------------------------
1 |
7 | * Jordi Boggiano
8 | *
9 | * For the full copyright and license information, please view the LICENSE
10 | * file that was distributed with this source code.
11 | */
12 |
13 | namespace Composer\Autoload;
14 |
15 | /**
16 | * ClassLoader implements a PSR-0 class loader
17 | *
18 | * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19 | *
20 | * $loader = new \Composer\Autoload\ClassLoader();
21 | *
22 | * // register classes with namespaces
23 | * $loader->add('Symfony\Component', __DIR__.'/component');
24 | * $loader->add('Symfony', __DIR__.'/framework');
25 | *
26 | * // activate the autoloader
27 | * $loader->register();
28 | *
29 | * // to enable searching the include path (eg. for PEAR packages)
30 | * $loader->setUseIncludePath(true);
31 | *
32 | * In this example, if you try to use a class in the Symfony\Component
33 | * namespace or one of its children (Symfony\Component\Console for instance),
34 | * the autoloader will first look for the class under the component/
35 | * directory, and it will then fallback to the framework/ directory if not
36 | * found before giving up.
37 | *
38 | * This class is loosely based on the Symfony UniversalClassLoader.
39 | *
40 | * @author Fabien Potencier
41 | * @author Jordi Boggiano
42 | */
43 | class ClassLoader
44 | {
45 | // PSR-4
46 | private $prefixLengthsPsr4 = array();
47 | private $prefixDirsPsr4 = array();
48 | private $fallbackDirsPsr4 = array();
49 |
50 | // PSR-0
51 | private $prefixesPsr0 = array();
52 | private $fallbackDirsPsr0 = array();
53 |
54 | private $useIncludePath = false;
55 | private $classMap = array();
56 |
57 | public function getPrefixes()
58 | {
59 | return call_user_func_array('array_merge', $this->prefixesPsr0);
60 | }
61 |
62 | public function getPrefixesPsr4()
63 | {
64 | return $this->prefixDirsPsr4;
65 | }
66 |
67 | public function getFallbackDirs()
68 | {
69 | return $this->fallbackDirsPsr0;
70 | }
71 |
72 | public function getFallbackDirsPsr4()
73 | {
74 | return $this->fallbackDirsPsr4;
75 | }
76 |
77 | public function getClassMap()
78 | {
79 | return $this->classMap;
80 | }
81 |
82 | /**
83 | * @param array $classMap Class to filename map
84 | */
85 | public function addClassMap(array $classMap)
86 | {
87 | if ($this->classMap) {
88 | $this->classMap = array_merge($this->classMap, $classMap);
89 | } else {
90 | $this->classMap = $classMap;
91 | }
92 | }
93 |
94 | /**
95 | * Registers a set of PSR-0 directories for a given prefix, either
96 | * appending or prepending to the ones previously set for this prefix.
97 | *
98 | * @param string $prefix The prefix
99 | * @param array|string $paths The PSR-0 root directories
100 | * @param bool $prepend Whether to prepend the directories
101 | */
102 | public function add($prefix, $paths, $prepend = false)
103 | {
104 | if (!$prefix) {
105 | if ($prepend) {
106 | $this->fallbackDirsPsr0 = array_merge(
107 | (array) $paths,
108 | $this->fallbackDirsPsr0
109 | );
110 | } else {
111 | $this->fallbackDirsPsr0 = array_merge(
112 | $this->fallbackDirsPsr0,
113 | (array) $paths
114 | );
115 | }
116 |
117 | return;
118 | }
119 |
120 | $first = $prefix[0];
121 | if (!isset($this->prefixesPsr0[$first][$prefix])) {
122 | $this->prefixesPsr0[$first][$prefix] = (array) $paths;
123 |
124 | return;
125 | }
126 | if ($prepend) {
127 | $this->prefixesPsr0[$first][$prefix] = array_merge(
128 | (array) $paths,
129 | $this->prefixesPsr0[$first][$prefix]
130 | );
131 | } else {
132 | $this->prefixesPsr0[$first][$prefix] = array_merge(
133 | $this->prefixesPsr0[$first][$prefix],
134 | (array) $paths
135 | );
136 | }
137 | }
138 |
139 | /**
140 | * Registers a set of PSR-4 directories for a given namespace, either
141 | * appending or prepending to the ones previously set for this namespace.
142 | *
143 | * @param string $prefix The prefix/namespace, with trailing '\\'
144 | * @param array|string $paths The PSR-0 base directories
145 | * @param bool $prepend Whether to prepend the directories
146 | *
147 | * @throws \InvalidArgumentException
148 | */
149 | public function addPsr4($prefix, $paths, $prepend = false)
150 | {
151 | if (!$prefix) {
152 | // Register directories for the root namespace.
153 | if ($prepend) {
154 | $this->fallbackDirsPsr4 = array_merge(
155 | (array) $paths,
156 | $this->fallbackDirsPsr4
157 | );
158 | } else {
159 | $this->fallbackDirsPsr4 = array_merge(
160 | $this->fallbackDirsPsr4,
161 | (array) $paths
162 | );
163 | }
164 | } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
165 | // Register directories for a new namespace.
166 | $length = strlen($prefix);
167 | if ('\\' !== $prefix[$length - 1]) {
168 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
169 | }
170 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
171 | $this->prefixDirsPsr4[$prefix] = (array) $paths;
172 | } elseif ($prepend) {
173 | // Prepend directories for an already registered namespace.
174 | $this->prefixDirsPsr4[$prefix] = array_merge(
175 | (array) $paths,
176 | $this->prefixDirsPsr4[$prefix]
177 | );
178 | } else {
179 | // Append directories for an already registered namespace.
180 | $this->prefixDirsPsr4[$prefix] = array_merge(
181 | $this->prefixDirsPsr4[$prefix],
182 | (array) $paths
183 | );
184 | }
185 | }
186 |
187 | /**
188 | * Registers a set of PSR-0 directories for a given prefix,
189 | * replacing any others previously set for this prefix.
190 | *
191 | * @param string $prefix The prefix
192 | * @param array|string $paths The PSR-0 base directories
193 | */
194 | public function set($prefix, $paths)
195 | {
196 | if (!$prefix) {
197 | $this->fallbackDirsPsr0 = (array) $paths;
198 | } else {
199 | $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
200 | }
201 | }
202 |
203 | /**
204 | * Registers a set of PSR-4 directories for a given namespace,
205 | * replacing any others previously set for this namespace.
206 | *
207 | * @param string $prefix The prefix/namespace, with trailing '\\'
208 | * @param array|string $paths The PSR-4 base directories
209 | *
210 | * @throws \InvalidArgumentException
211 | */
212 | public function setPsr4($prefix, $paths)
213 | {
214 | if (!$prefix) {
215 | $this->fallbackDirsPsr4 = (array) $paths;
216 | } else {
217 | $length = strlen($prefix);
218 | if ('\\' !== $prefix[$length - 1]) {
219 | throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
220 | }
221 | $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
222 | $this->prefixDirsPsr4[$prefix] = (array) $paths;
223 | }
224 | }
225 |
226 | /**
227 | * Turns on searching the include path for class files.
228 | *
229 | * @param bool $useIncludePath
230 | */
231 | public function setUseIncludePath($useIncludePath)
232 | {
233 | $this->useIncludePath = $useIncludePath;
234 | }
235 |
236 | /**
237 | * Can be used to check if the autoloader uses the include path to check
238 | * for classes.
239 | *
240 | * @return bool
241 | */
242 | public function getUseIncludePath()
243 | {
244 | return $this->useIncludePath;
245 | }
246 |
247 | /**
248 | * Registers this instance as an autoloader.
249 | *
250 | * @param bool $prepend Whether to prepend the autoloader or not
251 | */
252 | public function register($prepend = false)
253 | {
254 | spl_autoload_register(array($this, 'loadClass'), true, $prepend);
255 | }
256 |
257 | /**
258 | * Unregisters this instance as an autoloader.
259 | */
260 | public function unregister()
261 | {
262 | spl_autoload_unregister(array($this, 'loadClass'));
263 | }
264 |
265 | /**
266 | * Loads the given class or interface.
267 | *
268 | * @param string $class The name of the class
269 | * @return bool|null True if loaded, null otherwise
270 | */
271 | public function loadClass($class)
272 | {
273 | if ($file = $this->findFile($class)) {
274 | includeFile($file);
275 |
276 | return true;
277 | }
278 | }
279 |
280 | /**
281 | * Finds the path to the file where the class is defined.
282 | *
283 | * @param string $class The name of the class
284 | *
285 | * @return string|false The path if found, false otherwise
286 | */
287 | public function findFile($class)
288 | {
289 | // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
290 | if ('\\' == $class[0]) {
291 | $class = substr($class, 1);
292 | }
293 |
294 | // class map lookup
295 | if (isset($this->classMap[$class])) {
296 | return $this->classMap[$class];
297 | }
298 |
299 | $file = $this->findFileWithExtension($class, '.php');
300 |
301 | // Search for Hack files if we are running on HHVM
302 | if ($file === null && defined('HHVM_VERSION')) {
303 | $file = $this->findFileWithExtension($class, '.hh');
304 | }
305 |
306 | if ($file === null) {
307 | // Remember that this class does not exist.
308 | return $this->classMap[$class] = false;
309 | }
310 |
311 | return $file;
312 | }
313 |
314 | private function findFileWithExtension($class, $ext)
315 | {
316 | // PSR-4 lookup
317 | $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
318 |
319 | $first = $class[0];
320 | if (isset($this->prefixLengthsPsr4[$first])) {
321 | foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
322 | if (0 === strpos($class, $prefix)) {
323 | foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
324 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
325 | return $file;
326 | }
327 | }
328 | }
329 | }
330 | }
331 |
332 | // PSR-4 fallback dirs
333 | foreach ($this->fallbackDirsPsr4 as $dir) {
334 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
335 | return $file;
336 | }
337 | }
338 |
339 | // PSR-0 lookup
340 | if (false !== $pos = strrpos($class, '\\')) {
341 | // namespaced class name
342 | $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
343 | . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
344 | } else {
345 | // PEAR-like class name
346 | $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
347 | }
348 |
349 | if (isset($this->prefixesPsr0[$first])) {
350 | foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
351 | if (0 === strpos($class, $prefix)) {
352 | foreach ($dirs as $dir) {
353 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
354 | return $file;
355 | }
356 | }
357 | }
358 | }
359 | }
360 |
361 | // PSR-0 fallback dirs
362 | foreach ($this->fallbackDirsPsr0 as $dir) {
363 | if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
364 | return $file;
365 | }
366 | }
367 |
368 | // PSR-0 include paths.
369 | if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
370 | return $file;
371 | }
372 | }
373 | }
374 |
375 | /**
376 | * Scope isolated include.
377 | *
378 | * Prevents access to $this/self from included files.
379 | */
380 | function includeFile($file)
381 | {
382 | include $file;
383 | }
384 |
--------------------------------------------------------------------------------
/src/scripts/conf.php:
--------------------------------------------------------------------------------
1 | 1, 'remove' => 1, 'refresh' => 1, 'list' => 1, 'alias' => 1, 'unalias' => 1, 'select' => 0, 'addAll' => 0, 'nuke' => 0];
27 | private $currentCmd = [];
28 | private $currentConfig;
29 | private $query;
30 | private $documentations;
31 | private $aliases;
32 | private $workflows;
33 | private $pList;
34 | private $rootPath;
35 |
36 | public function __construct($query) {
37 | $this->query = $query;
38 | $this->workflows = new \Workflows();
39 | $cache = $this->workflows->cache();
40 | if ($cache !== false) {
41 | self::$cacheDirectory = $cache . '/';
42 | }
43 |
44 | $this->loadAliases();
45 | $this->loadDocs();
46 | $this->parseCommand($query);
47 | $this->buildRootPath();
48 | $this->openPlist();
49 | $this->setDocumentations();
50 |
51 | if (method_exists($this, $this->currentCmd[0] . 'Cmd')) {
52 | $this->{$this->currentCmd[0] . 'Cmd'}();
53 | }
54 | }
55 |
56 | private function openPlist() {
57 | $this->pList = new CFPropertyList($this->rootPath . '/info.plist');
58 | $this->pList = $this->pList->toArray();
59 | $this->regeneratePlist();
60 | }
61 |
62 | private function parseCommand($rawQuery) {
63 | $this->currentCmd = explode(' ', $rawQuery);
64 | if (!empty($this->currentCmd)) {
65 | $commandToCheck = (strpos($this->currentCmd[0], 'select') === 0) ? 'select' : $this->currentCmd[0];
66 | return (
67 | ($commandToCheck === 'select' || key_exists($commandToCheck, $this->commands)) &&
68 | (count($this->currentCmd) - 1 >= $this->commands[$commandToCheck])
69 | );
70 | } else {
71 | $this->currentCmd[0] = '';
72 | }
73 | return false;
74 | }
75 |
76 | private function buildRootPath() {
77 | $this->rootPath = str_replace('/scripts', '', $this->workflows->path());
78 | }
79 |
80 | private function flushToAlfred() {
81 | echo $this->workflows->toxml();
82 | }
83 |
84 | private function regeneratePlist() {
85 | $buildPlist = function ($rootPath, $documentations, $aliases, $variables) { // $documentations are used in the template
86 | ob_start();
87 | include $rootPath . '/scripts/plist.phtml';
88 | $fileContent = ob_get_contents();
89 | ob_end_clean();
90 | file_put_contents($rootPath . '/info.plist', $fileContent);
91 | };
92 | $buildPlist($this->rootPath, $this->currentConfig, $this->aliases, $this->pList['variables']);
93 | }
94 |
95 | private function setDocumentations() {
96 | $docFile = self::$cacheDirectory . 'docs.json';
97 | // Keep the docs in cache during 7 days
98 | if (!file_exists($docFile) || (filemtime($docFile) <= time() - 86400 * 7) || is_null(@json_decode(file_get_contents($docFile)))) {
99 | file_put_contents($docFile, $this->workflows->fetch(self::$baseUrl . 'docs/docs.json'));
100 | }
101 | $docs = @json_decode(file_get_contents($docFile));
102 | $this->documentations = [];
103 | if (is_array($docs)) {
104 | foreach ($docs as $doc) {
105 | $doc->fullName = $doc->name . (!empty($doc->version) ? ' ' . $doc->version : '');
106 | $this->documentations[$doc->slug] = $doc;
107 | }
108 | }
109 | }
110 |
111 | private function loadAliases() {
112 | $aliasesFile = $this->workflows->data() . '/aliases.json';
113 | $this->aliases = @json_decode(file_get_contents($aliasesFile), true);
114 | if (!is_array($this->aliases)) {
115 | $this->aliases = [];
116 | $this->saveAliases();
117 | }
118 | }
119 |
120 | private function saveAliases() {
121 | $aliasesFile = $this->workflows->data() . '/aliases.json';
122 | file_put_contents($aliasesFile, json_encode($this->aliases));
123 | }
124 |
125 | private function loadDocs() {
126 | $docsFile = $this->workflows->data() . '/docs.json';
127 | $this->currentConfig = @json_decode(file_get_contents($docsFile), true);
128 | if (!is_array($this->currentConfig)) {
129 | $this->currentConfig = [];
130 | $this->saveDocs();
131 | } else {
132 | foreach ($this->currentConfig as $key => $doc) {
133 | $this->currentConfig[$key] = (object) $doc;
134 | }
135 | }
136 | }
137 |
138 | private function saveDocs() {
139 | $docsFile = $this->workflows->data() . '/docs.json';
140 | file_put_contents($docsFile, json_encode($this->currentConfig));
141 | }
142 |
143 | private function filter($search, $collection) {
144 | $filtered = array_filter(
145 | $collection,
146 | function ($element) use ($search) {
147 | return ($search !== '') ? stripos($element->slug, $search) !== false : true;
148 | }
149 | );
150 | uasort($filtered, function ($elementA, $elementB) {
151 | return $elementA->slug >= $elementB->slug;
152 | });
153 | return $filtered;
154 | }
155 |
156 | private function flatten($arr) {
157 | $flattenAliases = [];
158 | array_walk_recursive($arr, function ($a) use (&$flattenAliases) {
159 | $flattenAliases[] = $a;
160 | });
161 | return $flattenAliases;
162 | }
163 |
164 | private function helpText($title, $subtitle = '') {
165 | $this->workflows->result(
166 | '',
167 | '',
168 | $title,
169 | $subtitle,
170 | '',
171 | 'no',
172 | "{$this->currentCmd[1]} "
173 | );
174 | }
175 |
176 | private function selectAddCmd() {
177 | $search = (isset($this->currentCmd[1])) ? $this->currentCmd[1] : '';
178 | $availableDocs = array_diff_key($this->documentations, $this->currentConfig);
179 | $availableDocs = $this->filter($search, $availableDocs);
180 | foreach ($availableDocs as $doc) {
181 | $this->workflows->result(
182 | $doc->slug,
183 | "add " . $doc->slug,
184 | $doc->fullName,
185 | '',
186 | $this->getIcon($doc),
187 | 'yes',
188 | $doc->slug
189 | );
190 | }
191 | if (count($availableDocs) === 0) {
192 | $this->helpText('No results.');
193 | }
194 | $this->flushToAlfred();
195 | }
196 |
197 | private function addCmd() {
198 | $doc = $this->documentations[$this->currentCmd[1]];
199 | $this->currentConfig[$this->currentCmd[1]] = $doc;
200 | $this->regeneratePlist();
201 | $this->saveDocs();
202 | if (!file_exists($this->rootPath . '/' . $doc->slug . '.png')) {
203 | @copy($this->rootPath . '/' . $doc->type . '.png', $this->rootPath . '/' . $doc->slug . '.png');
204 | }
205 | echo $this->currentCmd[1] . ' added!';
206 | }
207 |
208 | private function selectRemoveCmd() {
209 | $search = isset($this->currentCmd[1]) ? $this->currentCmd[1] : '';
210 | $availableDocs = $this->filter($search, $this->currentConfig);
211 | foreach ($availableDocs as $doc) {
212 | $this->workflows->result(
213 | $doc->slug,
214 | "remove " . $doc->slug,
215 | $doc->fullName,
216 | '',
217 | $this->getIcon($doc),
218 | 'yes',
219 | $doc->slug
220 | );
221 | }
222 | if (count($availableDocs) === 0) {
223 | $this->helpText('No results.');
224 | }
225 | $this->flushToAlfred();
226 | }
227 |
228 | private function removeCmd() {
229 | unset($this->currentConfig[$this->currentCmd[1]]);
230 | unset($this->aliases[$this->currentCmd[1]]);
231 | $this->regeneratePlist();
232 | $this->saveDocs();
233 | $this->saveAliases();
234 | echo $this->currentCmd[1] . ' removed!';
235 | }
236 |
237 | private function selectRefreshCmd() {
238 | $search = isset($this->currentCmd[1]) ? $this->currentCmd[1] : '';
239 | $availableDocs = $this->filter($search, $this->currentConfig);
240 |
241 | if (count($availableDocs) === 0) {
242 | $this->helpText('No results.');
243 | } else {
244 | $this->workflows->result(
245 | 'all',
246 | "refresh all",
247 | "All docs",
248 | '',
249 | $this->rootPath . '/all.png'
250 | );
251 | foreach ($availableDocs as $doc) {
252 | $this->workflows->result(
253 | $doc->slug,
254 | "refresh " . $doc->slug,
255 | $doc->fullName,
256 | '',
257 | $this->getIcon($doc),
258 | 'yes',
259 | $doc->slug
260 | );
261 | }
262 | }
263 | $this->flushToAlfred();
264 | }
265 |
266 | private function refreshCmd() {
267 | $updateAll = ($this->currentCmd[1] === 'all');
268 | $docToUpdate = $updateAll ? $this->currentConfig : [$this->currentCmd[1] => $this->currentConfig[$this->currentCmd[1]]];
269 | foreach ($docToUpdate as $doc) {
270 | file_put_contents(
271 | self::$cacheDirectory . $doc->slug . '.json',
272 | $this->workflows->fetch(self::$baseUrl . 'docs/' . $doc->slug . '/index.json')
273 | );
274 | }
275 | echo (($updateAll) ? 'All data docs' : $this->currentCmd[1] . ' doc') . ' updated!';
276 | }
277 |
278 | private function listCmd() {
279 | $search = (isset($this->currentCmd[1])) ? $this->currentCmd[1] : '';
280 | $docs = $this->filter($search, $this->documentations);
281 | foreach ($docs as $doc) {
282 | $this->workflows->result(
283 | $doc->slug,
284 | json_encode($doc),
285 | $doc->fullName,
286 | (isset($this->currentConfig[$doc->slug])) ? 'Already in your doc list' : '',
287 | $this->getIcon($doc),
288 | 'yes',
289 | $doc->slug
290 | );
291 | }
292 | $this->flushToAlfred();
293 | }
294 |
295 | private function getIcon($doc) {
296 | if (file_exists($this->rootPath . '/' . $doc->slug . '.png')) {
297 | return $this->rootPath . '/' . $doc->slug . '.png';
298 | } else {
299 | return $this->rootPath . '/' . $doc->type . '.png';
300 | }
301 | }
302 |
303 | private function addAllCmd() {
304 | $this->currentConfig = $this->documentations;
305 | $this->regeneratePlist();
306 | $this->saveDocs();
307 | echo 'All docs added!';
308 | }
309 |
310 | private function nukeCmd() {
311 | $this->currentConfig = [];
312 | $this->aliases = [];
313 | $this->regeneratePlist();
314 | $this->saveDocs();
315 | $this->saveAliases();
316 | echo 'All docs removed!';
317 | }
318 |
319 | private function selectAliasCmd() {
320 | if (!isset($this->currentCmd[1]) || empty($this->currentCmd[1]) ||
321 | !isset($this->currentCmd[2]) || empty($this->currentCmd[2])
322 | ) {
323 |
324 | $this->helpText('Enter an alias and a documentation', 'e.g.: cdoc:alias ng angular~4_typescript');
325 | } else {
326 | $alias = $this->currentCmd[1];
327 | $docName = $this->currentCmd[2];
328 |
329 | $availableDocs = $this->filter($docName, $this->currentConfig);
330 | foreach ($availableDocs as $doc) {
331 | $this->workflows->result(
332 | $doc->slug,
333 | "alias $alias $doc->slug",
334 | $doc->fullName,
335 | '',
336 | $this->getIcon($doc),
337 | 'yes',
338 | "$alias $doc->slug"
339 | );
340 | }
341 | if (count($availableDocs) === 0) {
342 | $this->helpText('No results.');
343 | }
344 | }
345 | $this->flushToAlfred();
346 | }
347 |
348 | private function aliasCmd() {
349 | $alias = $this->currentCmd[1];
350 | $docName = $this->currentCmd[2];
351 | $docExists = isset($this->documentations[$docName]);
352 | if ($docExists) {
353 | if (!isset($this->aliases[$docName])) {
354 | $this->aliases[$docName] = [];
355 | }
356 | $this->aliases[$docName][] = $alias;
357 | }
358 |
359 | $this->regeneratePlist();
360 | $this->saveAliases();
361 |
362 | echo "Alias $alias to $docName added!";
363 | }
364 |
365 | private function selectUnaliasCmd() {
366 | $search = isset($this->currentCmd[1]) ? $this->currentCmd[1] : '';
367 | $aliases = $this->flatten($this->aliases);
368 | if (!empty($search)) {
369 | $aliases = array_filter(
370 | $aliases,
371 | function ($element) use ($search) {
372 | return ($search !== '') ? stripos($element, $search) !== false : true;
373 | }
374 | );
375 | }
376 | sort($aliases);
377 | foreach ($aliases as $alias) {
378 | $this->workflows->result(
379 | $alias,
380 | "unalias $alias",
381 | $alias,
382 | '',
383 | '',
384 | 'yes',
385 | $alias
386 | );
387 | }
388 | if (count($aliases) === 0) {
389 | $this->helpText('No results.');
390 | }
391 | $this->flushToAlfred();
392 | }
393 |
394 | private function unaliasCmd() {
395 | $alias = $this->currentCmd[1];
396 | foreach ($this->aliases as $docName => $docAliases) {
397 | if (in_array($alias, $docAliases)) {
398 | $this->aliases[$docName] = array_diff($docAliases, [$alias]);
399 | }
400 | if (count($this->aliases[$docName]) === 0) {
401 | unset($this->aliases[$docName]);
402 | }
403 | }
404 | $this->regeneratePlist();
405 | $this->saveAliases();
406 |
407 | echo "Alias $alias to $docName removed!";
408 | }
409 |
410 | }
411 |
412 | $query = isset($query) ? $query : '';
413 | new DevDocsConf($query);
414 |
--------------------------------------------------------------------------------
/src/scripts/workflows.php:
--------------------------------------------------------------------------------
1 | path = exec('pwd');
31 | $this->home = exec('printf $HOME');
32 |
33 | if (file_exists('info.plist')):
34 | $this->bundle = $this->get('bundleid', 'info.plist');
35 | endif;
36 |
37 | if (!is_null($bundleid)):
38 | $this->bundle = $bundleid;
39 | endif;
40 |
41 | if (isset($_SERVER['alfred_workflow_cache'])) {
42 | $this->cache = $_SERVER['alfred_workflow_cache'];
43 | } else {
44 | $this->cache = $this->home . "/Library/Caches/com.runningwithcrayons.Alfred-2/Workflow Data/" . $this->bundle;
45 | }
46 |
47 | if (isset($_SERVER['alfred_workflow_data'])) {
48 | $this->data = $_SERVER['alfred_workflow_data'];
49 | } else {
50 | $this->data = $this->home . "/Library/Application Support/Alfred 2/Workflow Data/" . $this->bundle;
51 | }
52 |
53 | if (!file_exists($this->cache)):
54 | exec("mkdir '" . $this->cache . "'");
55 | endif;
56 |
57 | if (!file_exists($this->data)):
58 | exec("mkdir '" . $this->data . "'");
59 | endif;
60 |
61 | $this->results = array();
62 | }
63 |
64 | /**
65 | * Description:
66 | * Accepts no parameter and returns the value of the bundle id for the current workflow.
67 | * If no value is available, then false is returned.
68 | *
69 | * @param none
70 | * @return false if not available, bundle id value if available.
71 | */
72 | public function bundle() {
73 | if (is_null($this->bundle)):
74 | return false;
75 | else:
76 | return $this->bundle;
77 | endif;
78 | }
79 |
80 | /**
81 | * Description:
82 | * Accepts no parameter and returns the value of the path to the cache directory for your
83 | * workflow if it is available. Returns false if the value isn't available.
84 | *
85 | * @param none
86 | * @return false if not available, path to the cache directory for your workflow if available.
87 | */
88 | public function cache() {
89 | if (is_null($this->bundle)):
90 | return false;
91 | else:
92 | if (is_null($this->cache)):
93 | return false;
94 | else:
95 | return $this->cache;
96 | endif;
97 | endif;
98 | }
99 |
100 | /**
101 | * Description:
102 | * Accepts no parameter and returns the value of the path to the storage directory for your
103 | * workflow if it is available. Returns false if the value isn't available.
104 | *
105 | * @param none
106 | * @return false if not available, path to the storage directory for your workflow if available.
107 | */
108 | public function data() {
109 | if (is_null($this->bundle)):
110 | return false;
111 | else:
112 | if (is_null($this->data)):
113 | return false;
114 | else:
115 | return $this->data;
116 | endif;
117 | endif;
118 | }
119 |
120 | /**
121 | * Description:
122 | * Accepts no parameter and returns the value of the path to the current directory for your
123 | * workflow if it is available. Returns false if the value isn't available.
124 | *
125 | * @param none
126 | * @return false if not available, path to the current directory for your workflow if available.
127 | */
128 | public function path() {
129 | if (is_null($this->path)):
130 | return false;
131 | else:
132 | return $this->path;
133 | endif;
134 | }
135 |
136 | /**
137 | * Description:
138 | * Accepts no parameter and returns the value of the home path for the current user
139 | * Returns false if the value isn't available.
140 | *
141 | * @param none
142 | * @return false if not available, home path for the current user if available.
143 | */
144 | public function home() {
145 | if (is_null($this->home)):
146 | return false;
147 | else:
148 | return $this->home;
149 | endif;
150 | }
151 |
152 | /**
153 | * Description:
154 | * Returns an array of available result items
155 | *
156 | * @param none
157 | * @return array - list of result items
158 | */
159 | public function results() {
160 | return $this->results;
161 | }
162 |
163 | /**
164 | * Description:
165 | * Convert an associative array into XML format
166 | *
167 | * @param $a - An associative array to convert
168 | * @param $format - format of data being passed (json or array), defaults to array
169 | * @return - XML string representation of the array
170 | */
171 | public function toxml($a = null, $format = 'array') {
172 |
173 | if ($format == 'json'):
174 | $a = json_decode($a, true);
175 | endif;
176 |
177 | if (is_null($a) && !empty($this->results)):
178 | $a = $this->results;
179 | elseif (is_null($a) && empty($this->results)):
180 | return false;
181 | endif;
182 |
183 | $items = new SimpleXMLElement(""); // Create new XML element
184 |
185 | foreach ($a as $b): // Lop through each object in the array
186 | $c = $items->addChild('item'); // Add a new 'item' element for each object
187 | $c_keys = array_keys($b); // Grab all the keys for that item
188 | foreach ($c_keys as $key): // For each of those keys
189 | if ($key == 'uid'):
190 | $c->addAttribute('uid', $b[$key]);
191 | elseif ($key == 'arg'):
192 | $c->addAttribute('arg', $b[$key]);
193 | elseif ($key == 'type'):
194 | $c->addAttribute('type', $b[$key]);
195 | elseif ($key == 'valid'):
196 | if ($b[$key] == 'yes' || $b[$key] == 'no'):
197 | $c->addAttribute('valid', $b[$key]);
198 | endif;
199 | elseif ($key == 'autocomplete'):
200 | $c->addAttribute('autocomplete', $b[$key]);
201 | elseif ($key == 'icon'):
202 | if (substr($b[$key], 0, 9) == 'fileicon:'):
203 | $val = substr($b[$key], 9);
204 | $c->$key = $val;
205 | $c->$key->addAttribute('type', 'fileicon');
206 | elseif (substr($b[$key], 0, 9) == 'filetype:'):
207 | $val = substr($b[$key], 9);
208 | $c->$key = $val;
209 | $c->$key->addAttribute('type', 'filetype');
210 | else:
211 | $c->$key = $b[$key];
212 | endif;
213 | else:
214 | $c->$key = $b[$key];
215 | endif;
216 | endforeach;
217 | endforeach;
218 |
219 | return $items->asXML(); // Return XML string representation of the array
220 |
221 | }
222 |
223 | /**
224 | * Description:
225 | * Remove all items from an associative array that do not have a value
226 | *
227 | * @param $a - Associative array
228 | * @return bool
229 | */
230 | private function empty_filter($a) {
231 | if ($a == '' || $a == null): // if $a is empty or null
232 | return false; // return false, else, return true
233 | else:
234 | return true;
235 | endif;
236 | }
237 |
238 | /**
239 | * Description:
240 | * Save values to a specified plist. If the first parameter is an associative
241 | * array, then the second parameter becomes the plist file to save to. If the
242 | * first parameter is string, then it is assumed that the first parameter is
243 | * the label, the second parameter is the value, and the third parameter is
244 | * the plist file to save the data to.
245 | *
246 | * @param $a - associative array of values to save
247 | * @param $b - the value of the setting
248 | * @param $c - the plist to save the values into
249 | * @return string - execution output
250 | */
251 | public function set($a = null, $b = null, $c = null) {
252 | if (is_array($a)):
253 | if (file_exists($b)):
254 | if (file_exists($this->path . '/' . $b)):
255 | $b = $this->path . '/' . $b;
256 | endif;
257 | elseif (file_exists($this->data . "/" . $b)):
258 | $b = $this->data . "/" . $b;
259 | elseif (file_exists($this->cache . "/" . $b)):
260 | $b = $this->cache . "/" . $b;
261 | else:
262 | $b = $this->data . "/" . $b;
263 | endif;
264 | else:
265 | if (file_exists($c)):
266 | if (file_exists($this->path . '/' . $c)):
267 | $c = $this->path . '/' . $c;
268 | endif;
269 | elseif (file_exists($this->data . "/" . $c)):
270 | $c = $this->data . "/" . $c;
271 | elseif (file_exists($this->cache . "/" . $c)):
272 | $c = $this->cache . "/" . $c;
273 | else:
274 | $c = $this->data . "/" . $c;
275 | endif;
276 | endif;
277 |
278 | if (is_array($a)):
279 | foreach ($a as $k => $v):
280 | exec('defaults write "' . $b . '" ' . $k . ' "' . $v . '"');
281 | endforeach;
282 | else:
283 | exec('defaults write "' . $c . '" ' . $a . ' "' . $b . '"');
284 | endif;
285 | }
286 |
287 | /**
288 | * Description:
289 | * Read a value from the specified plist
290 | *
291 | * @param $a - the value to read
292 | * @param $b - plist to read the values from
293 | * @return bool false if not found, string if found
294 | */
295 | public function get($a, $b) {
296 |
297 | if (file_exists($b)):
298 | if (file_exists($this->path . '/' . $b)):
299 | $b = $this->path . '/' . $b;
300 | endif;
301 | elseif (file_exists($this->data . "/" . $b)):
302 | $b = $this->data . "/" . $b;
303 | elseif (file_exists($this->cache . "/" . $b)):
304 | $b = $this->cache . "/" . $b;
305 | else:
306 | return false;
307 | endif;
308 |
309 | exec('defaults read "' . $b . '" ' . $a, $out); // Execute system call to read plist value
310 |
311 | if ($out == ""):
312 | return false;
313 | endif;
314 |
315 | $out = is_array($out) && !empty($out) ? $out[0] : false;
316 | return $out; // Return item value
317 | }
318 |
319 | /**
320 | * Description:
321 | * Read data from a remote file/url, essentially a shortcut for curl
322 | *
323 | * @param $url - URL to request
324 | * @param $options - Array of curl options
325 | * @return result from curl_exec
326 | */
327 | public function request($url = null, $options = null) {
328 | if (is_null($url)):
329 | return false;
330 | endif;
331 |
332 | $defaults = array( // Create a list of default curl options
333 | CURLOPT_RETURNTRANSFER => true, // Returns the result as a string
334 | CURLOPT_URL => $url, // Sets the url to request
335 | CURLOPT_FRESH_CONNECT => true
336 | );
337 |
338 | if ($options):
339 | foreach ($options as $k => $v):
340 | $defaults[$k] = $v;
341 | endforeach;
342 | endif;
343 |
344 | array_filter($defaults, // Filter out empty options from the array
345 | array($this, 'empty_filter'));
346 |
347 | $ch = curl_init(); // Init new curl object
348 | curl_setopt_array($ch, $defaults); // Set curl options
349 | $out = curl_exec($ch); // Request remote data
350 | $err = curl_error($ch);
351 | curl_close($ch); // End curl request
352 |
353 | if ($err):
354 | return $err;
355 | else:
356 | return $out;
357 | endif;
358 | }
359 |
360 | /**
361 | * Description:
362 | * Allows searching the local hard drive using mdfind
363 | *
364 | * @param $query - search string
365 | * @return array - array of search results
366 | */
367 | public function mdfind($query) {
368 | exec('mdfind "' . $query . '"', $results);
369 | return $results;
370 | }
371 |
372 | public function delete($a) {
373 | if (file_exists($a)):
374 | if (file_exists($this->path . '/' . $a)):
375 | unlink($this->path . '/' . $a);
376 | endif;
377 | elseif (file_exists($this->data . "/" . $a)):
378 | unlink($this->data . "/" . $a);
379 | elseif (file_exists($this->cache . "/" . $a)):
380 | unlink($this->cache . "/" . $a);
381 | endif;
382 | }
383 |
384 | /**
385 | * Description:
386 | * Accepts data and a string file name to store data to local file as cache
387 | *
388 | * @param array - data to save to file
389 | * @param file - filename to write the cache data to
390 | * @return none
391 | */
392 | public function write($a, $b) {
393 | if (file_exists($b)):
394 | if (file_exists($this->path . '/' . $b)):
395 | $b = $this->path . '/' . $b;
396 | endif;
397 | elseif (file_exists($this->data . "/" . $b)):
398 | $b = $this->data . "/" . $b;
399 | elseif (file_exists($this->cache . "/" . $b)):
400 | $b = $this->cache . "/" . $b;
401 | else:
402 | $b = $this->data . "/" . $b;
403 | endif;
404 |
405 | if (is_array($a)):
406 | $a = json_encode($a);
407 | file_put_contents($b, $a);
408 | return true;
409 | elseif (is_string($a)):
410 | file_put_contents($b, $a);
411 | return true;
412 | else:
413 | return false;
414 | endif;
415 | }
416 |
417 | /**
418 | * Description:
419 | * Returns data from a local cache file
420 | *
421 | * @param file - filename to read the cache data from
422 | * @return false if the file cannot be found, the file data if found. If the file
423 | * format is json encoded, then a json object is returned.
424 | */
425 | public function read($a) {
426 | if (file_exists($a)):
427 | if (file_exists($this->path . '/' . $a)):
428 | $a = $this->path . '/' . $a;
429 | endif;
430 | elseif (file_exists($this->data . "/" . $a)):
431 | $a = $this->data . "/" . $a;
432 | elseif (file_exists($this->cache . "/" . $a)):
433 | $a = $this->cache . "/" . $a;
434 | else:
435 | return false;
436 | endif;
437 |
438 | $out = file_get_contents($a);
439 | if (!is_null(json_decode($out))):
440 | $out = json_decode($out);
441 | endif;
442 |
443 | return $out;
444 | }
445 |
446 | public function filetime($a) {
447 | if (file_exists($a)):
448 | if (file_exists($this->path . '/' . $a)):
449 | return filemtime($this->path . '/' . $a);
450 | endif;
451 | elseif (file_exists($this->data . "/" . $a)):
452 | return filemtime($this->data . '/' . $a);
453 | elseif (file_exists($this->cache . "/" . $a)):
454 | return filemtime($this->cache . '/' . $a);
455 | endif;
456 |
457 | return false;
458 | }
459 |
460 | /**
461 | * Description:
462 | * Helper function that just makes it easier to pass values into a function
463 | * and create an array result to be passed back to Alfred
464 | *
465 | * @param $uid - the uid of the result, should be unique
466 | * @param $arg - the argument that will be passed on
467 | * @param $title - The title of the result item
468 | * @param $sub - The subtitle text for the result item
469 | * @param $icon - the icon to use for the result item
470 | * @param $valid - sets whether the result item can be actioned
471 | * @param $auto - the autocomplete value for the result item
472 | * @return array - array item to be passed back to Alfred
473 | */
474 | public function result($uid, $arg, $title, $sub, $icon, $valid = 'yes', $auto = null, $type = null) {
475 | $temp = array(
476 | 'uid' => $uid,
477 | 'arg' => $arg,
478 | 'title' => $title,
479 | 'subtitle' => $sub,
480 | 'icon' => $icon,
481 | 'valid' => $valid,
482 | 'autocomplete' => $auto,
483 | 'type' => $type
484 | );
485 |
486 | if (is_null($type)):
487 | unset($temp['type']);
488 | endif;
489 |
490 | array_push($this->results, $temp);
491 |
492 | return $temp;
493 | }
494 |
495 | public function fetch($url) {
496 | $httpProxy = isset($_ENV['HTTP_PROXY']) ? $_ENV['HTTP_PROXY'] : '';
497 | if (!empty($httpProxy)) {
498 | $context = array(
499 | 'http' => array(
500 | 'proxy' => $_ENV['HTTP_PROXY'],
501 | 'request_fulluri' => true
502 | )
503 | );
504 | $httpProxyAuth = isset($_ENV['HTTP_PROXY_AUTHORIZATION']) ? $_ENV['HTTP_PROXY_AUTHORIZATION'] : '';
505 | if (!empty($httpProxyAuth)) {
506 | $context['http']['header'] = "Proxy-Authorization: Basic $httpProxyAuth";
507 | }
508 | $stream = stream_context_create($context);
509 | return file_get_contents($url, false, $stream);
510 | } else {
511 | return file_get_contents($url);
512 | }
513 | }
514 |
515 | public function log($var) {
516 | ob_start();
517 | var_dump($var);
518 | $output = ob_get_contents();
519 | ob_end_clean();
520 | error_log($output);
521 | }
522 |
523 | }
524 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/src/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | bundleid
6 | com.yannickglt.alfred4.devdocs
7 | category
8 | Productivity
9 | connections
10 |
11 | addalltask
12 |
13 |
14 | destinationuid
15 | shownotificationwhencomplete
16 | modifiers
17 | 0
18 | modifiersubtext
19 |
20 | vitoclose
21 |
22 |
23 |
24 | addalltaskkeyword
25 |
26 |
27 | destinationuid
28 | addalltask
29 | modifiers
30 | 0
31 | modifiersubtext
32 |
33 | vitoclose
34 |
35 |
36 |
37 | addtask
38 |
39 |
40 | destinationuid
41 | dotaskbasedoncommand
42 | modifiers
43 | 0
44 | modifiersubtext
45 |
46 | vitoclose
47 |
48 |
49 |
50 | aliastask
51 |
52 |
53 | destinationuid
54 | dotaskbasedoncommand
55 | modifiers
56 | 0
57 | modifiersubtext
58 |
59 | vitoclose
60 |
61 |
62 |
63 | doc
64 |
65 |
66 | destinationuid
67 | output
68 | modifiers
69 | 0
70 | modifiersubtext
71 |
72 | vitoclose
73 |
74 |
75 |
76 | dotaskbasedoncommand
77 |
78 |
79 | destinationuid
80 | shownotificationwhencomplete
81 | modifiers
82 | 0
83 | modifiersubtext
84 |
85 | vitoclose
86 |
87 |
88 |
89 | nuketask
90 |
91 |
92 | destinationuid
93 | shownotificationwhencomplete
94 | modifiers
95 | 0
96 | modifiersubtext
97 |
98 | vitoclose
99 |
100 |
101 |
102 | nuketaskkeyword
103 |
104 |
105 | destinationuid
106 | nuketask
107 | modifiers
108 | 0
109 | modifiersubtext
110 |
111 | vitoclose
112 |
113 |
114 |
115 | refreshtask
116 |
117 |
118 | destinationuid
119 | dotaskbasedoncommand
120 | modifiers
121 | 0
122 | modifiersubtext
123 |
124 | vitoclose
125 |
126 |
127 |
128 | removetask
129 |
130 |
131 | destinationuid
132 | dotaskbasedoncommand
133 | modifiers
134 | 0
135 | modifiersubtext
136 |
137 | vitoclose
138 |
139 |
140 |
141 | unaliastask
142 |
143 |
144 | destinationuid
145 | dotaskbasedoncommand
146 | modifiers
147 | 0
148 | modifiersubtext
149 |
150 | vitoclose
151 |
152 |
153 |
154 |
155 | createdby
156 | Yannick Galatol
157 | description
158 | Alfred workflow for devdocs.io documentations
159 | disabled
160 |
161 | name
162 | devdocs
163 | objects
164 |
165 |
166 | config
167 |
168 | browser
169 |
170 | spaces
171 |
172 | url
173 | {query}
174 | utf8
175 |
176 |
177 | type
178 | alfred.workflow.action.openurl
179 | uid
180 | output
181 | version
182 | 1
183 |
184 |
185 | config
186 |
187 | lastpathcomponent
188 |
189 | onlyshowifquerypopulated
190 |
191 | removeextension
192 |
193 | text
194 |
195 | title
196 | {query}
197 |
198 | type
199 | alfred.workflow.output.notification
200 | uid
201 | shownotificationwhencomplete
202 | version
203 | 1
204 |
205 |
206 | config
207 |
208 | alfredfiltersresults
209 |
210 | alfredfiltersresultsmatchmode
211 | 0
212 | argumenttreatemptyqueryasnil
213 |
214 | argumenttrimmode
215 | 0
216 | argumenttype
217 | 0
218 | escaping
219 | 118
220 | keyword
221 | doc
222 | queuedelaycustom
223 | 1
224 | queuedelayimmediatelyinitially
225 |
226 | queuedelaymode
227 | 0
228 | queuemode
229 | 1
230 | runningsubtext
231 | Searching for "{query}"
232 | script
233 | $query = "{query}"; require_once("scripts/devdocs.php");
234 | scriptargtype
235 | 0
236 | scriptfile
237 |
238 | subtext
239 | Search for "{query}"
240 | title
241 | DevDocs
242 | type
243 | 1
244 | withspace
245 |
246 |
247 | type
248 | alfred.workflow.input.scriptfilter
249 | uid
250 | doc
251 | version
252 | 3
253 |
254 |
255 | config
256 |
257 | concurrently
258 |
259 | escaping
260 | 126
261 | script
262 | $query = "{query}"; require_once("scripts/conf.php");
263 | scriptargtype
264 | 0
265 | scriptfile
266 |
267 | type
268 | 1
269 |
270 | type
271 | alfred.workflow.action.script
272 | uid
273 | dotaskbasedoncommand
274 | version
275 | 2
276 |
277 |
278 | config
279 |
280 | alfredfiltersresults
281 |
282 | alfredfiltersresultsmatchmode
283 | 0
284 | argumenttreatemptyqueryasnil
285 |
286 | argumenttrimmode
287 | 0
288 | argumenttype
289 | 1
290 | escaping
291 | 118
292 | keyword
293 | cdoc:add
294 | queuedelaycustom
295 | 1
296 | queuedelayimmediatelyinitially
297 |
298 | queuedelaymode
299 | 0
300 | queuemode
301 | 1
302 | runningsubtext
303 |
304 | script
305 | $query = "selectAdd {query}"; require_once("scripts/conf.php");
306 | scriptargtype
307 | 0
308 | scriptfile
309 |
310 | subtext
311 |
312 | title
313 | Add a doc on DevDocs workflow
314 | type
315 | 1
316 | withspace
317 |
318 |
319 | type
320 | alfred.workflow.input.scriptfilter
321 | uid
322 | addtask
323 | version
324 | 3
325 |
326 |
327 | config
328 |
329 | alfredfiltersresults
330 |
331 | alfredfiltersresultsmatchmode
332 | 0
333 | argumenttreatemptyqueryasnil
334 |
335 | argumenttrimmode
336 | 0
337 | argumenttype
338 | 1
339 | escaping
340 | 118
341 | keyword
342 | cdoc:remove
343 | queuedelaycustom
344 | 1
345 | queuedelayimmediatelyinitially
346 |
347 | queuedelaymode
348 | 0
349 | queuemode
350 | 1
351 | runningsubtext
352 |
353 | script
354 | $query = "selectRemove {query}"; require_once("scripts/conf.php");
355 | scriptargtype
356 | 0
357 | scriptfile
358 |
359 | subtext
360 |
361 | title
362 | Remove a doc on DevDocs workflow
363 | type
364 | 1
365 | withspace
366 |
367 |
368 | type
369 | alfred.workflow.input.scriptfilter
370 | uid
371 | removetask
372 | version
373 | 3
374 |
375 |
376 | config
377 |
378 | alfredfiltersresults
379 |
380 | alfredfiltersresultsmatchmode
381 | 0
382 | argumenttreatemptyqueryasnil
383 |
384 | argumenttrimmode
385 | 0
386 | argumenttype
387 | 1
388 | escaping
389 | 118
390 | keyword
391 | cdoc:refresh
392 | queuedelaycustom
393 | 1
394 | queuedelayimmediatelyinitially
395 |
396 | queuedelaymode
397 | 0
398 | queuemode
399 | 1
400 | runningsubtext
401 |
402 | script
403 | $query = "selectRefresh {query}"; require_once("scripts/conf.php");
404 | scriptargtype
405 | 0
406 | scriptfile
407 |
408 | subtext
409 |
410 | title
411 | Refresh docs on DevDocs workflow
412 | type
413 | 1
414 | withspace
415 |
416 |
417 | type
418 | alfred.workflow.input.scriptfilter
419 | uid
420 | refreshtask
421 | version
422 | 3
423 |
424 |
425 | config
426 |
427 | alfredfiltersresults
428 |
429 | alfredfiltersresultsmatchmode
430 | 0
431 | argumenttreatemptyqueryasnil
432 |
433 | argumenttrimmode
434 | 0
435 | argumenttype
436 | 1
437 | escaping
438 | 118
439 | keyword
440 | cdoc:list
441 | queuedelaycustom
442 | 1
443 | queuedelayimmediatelyinitially
444 |
445 | queuedelaymode
446 | 0
447 | queuemode
448 | 1
449 | runningsubtext
450 |
451 | script
452 | $query = "list {query}"; require_once("scripts/conf.php");
453 | scriptargtype
454 | 0
455 | scriptfile
456 |
457 | subtext
458 |
459 | title
460 | List available docs on DevDocs workflow
461 | type
462 | 1
463 | withspace
464 |
465 |
466 | type
467 | alfred.workflow.input.scriptfilter
468 | uid
469 | listtask
470 | version
471 | 3
472 |
473 |
474 | config
475 |
476 | argumenttype
477 | 2
478 | keyword
479 | cdoc:all
480 | subtext
481 |
482 | text
483 | Add all available docs on DevDocs workflow
484 | withspace
485 |
486 |
487 | type
488 | alfred.workflow.input.keyword
489 | uid
490 | addalltaskkeyword
491 | version
492 | 1
493 |
494 |
495 | config
496 |
497 | concurrently
498 |
499 | escaping
500 | 118
501 | script
502 | $query = "addAll"; require_once("scripts/conf.php");
503 | scriptargtype
504 | 0
505 | scriptfile
506 |
507 | type
508 | 1
509 |
510 | type
511 | alfred.workflow.action.script
512 | uid
513 | addalltask
514 | version
515 | 2
516 |
517 |
518 | config
519 |
520 | argumenttype
521 | 2
522 | keyword
523 | cdoc:nuke
524 | subtext
525 |
526 | text
527 | Remove all docs on your DevDocs workflow
528 | withspace
529 |
530 |
531 | type
532 | alfred.workflow.input.keyword
533 | uid
534 | nuketaskkeyword
535 | version
536 | 1
537 |
538 |
539 | config
540 |
541 | concurrently
542 |
543 | escaping
544 | 118
545 | script
546 | $query = "nuke"; require_once("scripts/conf.php");
547 | scriptargtype
548 | 0
549 | scriptfile
550 |
551 | type
552 | 1
553 |
554 | type
555 | alfred.workflow.action.script
556 | uid
557 | nuketask
558 | version
559 | 2
560 |
561 |
562 | config
563 |
564 | alfredfiltersresults
565 |
566 | alfredfiltersresultsmatchmode
567 | 0
568 | argumenttreatemptyqueryasnil
569 |
570 | argumenttrimmode
571 | 0
572 | argumenttype
573 | 0
574 | escaping
575 | 118
576 | keyword
577 | cdoc:alias
578 | queuedelaycustom
579 | 1
580 | queuedelayimmediatelyinitially
581 |
582 | queuedelaymode
583 | 0
584 | queuemode
585 | 1
586 | runningsubtext
587 |
588 | script
589 | $query = "selectAlias {query}"; require_once("scripts/conf.php");
590 | scriptargtype
591 | 0
592 | scriptfile
593 |
594 | subtext
595 |
596 | title
597 | Create an alias for a documentation
598 | type
599 | 1
600 | withspace
601 |
602 |
603 | type
604 | alfred.workflow.input.scriptfilter
605 | uid
606 | aliastask
607 | version
608 | 3
609 |
610 |
611 | config
612 |
613 | alfredfiltersresults
614 |
615 | alfredfiltersresultsmatchmode
616 | 0
617 | argumenttreatemptyqueryasnil
618 |
619 | argumenttrimmode
620 | 0
621 | argumenttype
622 | 1
623 | escaping
624 | 118
625 | keyword
626 | cdoc:unalias
627 | queuedelaycustom
628 | 1
629 | queuedelayimmediatelyinitially
630 |
631 | queuedelaymode
632 | 0
633 | queuemode
634 | 1
635 | runningsubtext
636 |
637 | script
638 | $query = "selectUnalias {query}"; require_once("scripts/conf.php");
639 | scriptargtype
640 | 0
641 | scriptfile
642 |
643 | subtext
644 |
645 | title
646 | Remove an existing alias of a documentation
647 | type
648 | 1
649 | withspace
650 |
651 |
652 | type
653 | alfred.workflow.input.scriptfilter
654 | uid
655 | unaliastask
656 | version
657 | 3
658 |
659 |
660 | readme
661 |
662 | uidata
663 |
664 | addalltask
665 |
666 | xpos
667 | 500
668 | ypos
669 | 585
670 |
671 | addalltaskkeyword
672 |
673 | xpos
674 | 300
675 | ypos
676 | 585
677 |
678 | addtask
679 |
680 | xpos
681 | 300
682 | ypos
683 | 125
684 |
685 | aliastask
686 |
687 | xpos
688 | 300
689 | ypos
690 | 815
691 |
692 | doc
693 |
694 | xpos
695 | 300
696 | ypos
697 | 10
698 |
699 | dotaskbasedoncommand
700 |
701 | xpos
702 | 500
703 | ypos
704 | 125
705 |
706 | listtask
707 |
708 | xpos
709 | 300
710 | ypos
711 | 470
712 |
713 | nuketask
714 |
715 | xpos
716 | 500
717 | ypos
718 | 700
719 |
720 | nuketaskkeyword
721 |
722 | xpos
723 | 300
724 | ypos
725 | 700
726 |
727 | output
728 |
729 | xpos
730 | 500
731 | ypos
732 | 10
733 |
734 | refreshtask
735 |
736 | xpos
737 | 300
738 | ypos
739 | 355
740 |
741 | removetask
742 |
743 | xpos
744 | 300
745 | ypos
746 | 240
747 |
748 | shownotificationwhencomplete
749 |
750 | xpos
751 | 700
752 | ypos
753 | 10
754 |
755 | unaliastask
756 |
757 | xpos
758 | 300
759 | ypos
760 | 930
761 |
762 |
763 | variables
764 |
765 | BASE_URL
766 |
767 | CACHE_LIFE
768 |
769 | TEMPLATE
770 |
771 |
772 | variablesdontexport
773 |
774 | version
775 | 4.1.0
776 | webaddress
777 | https://github.com/yannickglt/alfred-devdocs
778 |
779 |
780 |
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFPropertyList.php:
--------------------------------------------------------------------------------
1 |
6 | * @author Christian Kruse
7 | * @package plist
8 | * @version $Id$
9 | * @example example-read-01.php Read an XML PropertyList
10 | * @example example-read-02.php Read a Binary PropertyList
11 | * @example example-read-03.php Read a PropertyList without knowing the type
12 | * @example example-create-01.php Using the CFPropertyList API
13 | * @example example-create-02.php Using {@link CFTypeDetector}
14 | * @example example-create-03.php Using {@link CFTypeDetector} with {@link CFDate} and {@link CFData}
15 | * @example example-modify-01.php Read, modify and save a PropertyList
16 | */
17 |
18 | namespace CFPropertyList;
19 | use \Iterator, \DOMDocument, \DOMException, DOMImplementation, DOMNode;
20 |
21 | /**
22 | * Require IOException, PListException, CFType and CFBinaryPropertyList
23 | */
24 | require_once(__DIR__.'/IOException.php');
25 | require_once(__DIR__.'/PListException.php');
26 | require_once(__DIR__.'/CFType.php');
27 | require_once(__DIR__.'/CFBinaryPropertyList.php');
28 | require_once(__DIR__.'/CFTypeDetector.php');
29 |
30 | /**
31 | * Property List
32 | * Interface for handling reading, editing and saving Property Lists as defined by Apple.
33 | * @author Rodney Rehm
34 | * @author Christian Kruse
35 | * @package plist
36 | * @example example-read-01.php Read an XML PropertyList
37 | * @example example-read-02.php Read a Binary PropertyList
38 | * @example example-read-03.php Read a PropertyList without knowing the type
39 | * @example example-create-01.php Using the CFPropertyList API
40 | * @example example-create-02.php Using {@link CFTypeDetector}
41 | * @example example-create-03.php Using {@link CFTypeDetector} with {@link CFDate} and {@link CFData}
42 | * @example example-create-04.php Using and extended {@link CFTypeDetector}
43 | */
44 | class CFPropertyList extends CFBinaryPropertyList implements Iterator {
45 | /**
46 | * Format constant for binary format
47 | * @var integer
48 | */
49 | const FORMAT_BINARY = 1;
50 |
51 | /**
52 | * Format constant for xml format
53 | * @var integer
54 | */
55 | const FORMAT_XML = 2;
56 |
57 | /**
58 | * Format constant for automatic format recognizing
59 | * @var integer
60 | */
61 | const FORMAT_AUTO = 0;
62 |
63 | /**
64 | * Path of PropertyList
65 | * @var string
66 | */
67 | protected $file = null;
68 |
69 | /**
70 | * Path of PropertyList
71 | * @var integer
72 | */
73 | protected $format = null;
74 |
75 | /**
76 | * CFType nodes
77 | * @var array
78 | */
79 | protected $value = array();
80 |
81 | /**
82 | * Position of iterator {@link http://php.net/manual/en/class.iterator.php}
83 | * @var integer
84 | */
85 | protected $iteratorPosition = 0;
86 |
87 | /**
88 | * List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
89 | * @var array
90 | */
91 | protected $iteratorKeys = null;
92 |
93 | /**
94 | * List of NodeNames to ClassNames for resolving plist-files
95 | * @var array
96 | */
97 | protected static $types = array(
98 | 'string' => 'CFString',
99 | 'real' => 'CFNumber',
100 | 'integer' => 'CFNumber',
101 | 'date' => 'CFDate',
102 | 'true' => 'CFBoolean',
103 | 'false' => 'CFBoolean',
104 | 'data' => 'CFData',
105 | 'array' => 'CFArray',
106 | 'dict' => 'CFDictionary'
107 | );
108 |
109 |
110 | /**
111 | * Create new CFPropertyList.
112 | * If a path to a PropertyList is specified, it is loaded automatically.
113 | * @param string $file Path of PropertyList
114 | * @param integer $format he format of the property list, see {@link FORMAT_XML}, {@link FORMAT_BINARY} and {@link FORMAT_AUTO}, defaults to {@link FORMAT_AUTO}
115 | * @throws IOException if file could not be read by {@link load()}
116 | * @uses $file for storing the current file, if specified
117 | * @uses load() for loading the plist-file
118 | */
119 | public function __construct($file=null,$format=self::FORMAT_AUTO) {
120 | $this->file = $file;
121 | $this->format = $format;
122 | if($this->file) $this->load();
123 | }
124 |
125 | /**
126 | * Load an XML PropertyList.
127 | * @param string $file Path of PropertyList, defaults to {@link $file}
128 | * @return void
129 | * @throws IOException if file could not be read
130 | * @throws DOMException if XML-file could not be read properly
131 | * @uses load() to actually load the file
132 | */
133 | public function loadXML($file=null) {
134 | $this->load($file,CFPropertyList::FORMAT_XML);
135 | }
136 |
137 | /**
138 | * Load an XML PropertyList.
139 | * @param resource $stream A stream containing the xml document.
140 | * @return void
141 | * @throws IOException if stream could not be read
142 | * @throws DOMException if XML-stream could not be read properly
143 | */
144 | public function loadXMLStream($stream) {
145 | if(($contents = stream_get_contents($stream)) === FALSE) throw IOException::notReadable('');
146 | $this->parse($contents,CFPropertyList::FORMAT_XML);
147 | }
148 |
149 | /**
150 | * Load an binary PropertyList.
151 | * @param string $file Path of PropertyList, defaults to {@link $file}
152 | * @return void
153 | * @throws IOException if file could not be read
154 | * @throws PListException if binary plist-file could not be read properly
155 | * @uses load() to actually load the file
156 | */
157 | public function loadBinary($file=null) {
158 | $this->load($file,CFPropertyList::FORMAT_BINARY);
159 | }
160 |
161 | /**
162 | * Load an binary PropertyList.
163 | * @param stream $stream Stream containing the PropertyList
164 | * @return void
165 | * @throws IOException if file could not be read
166 | * @throws PListException if binary plist-file could not be read properly
167 | * @uses parse() to actually load the file
168 | */
169 | public function loadBinaryStream($stream) {
170 | if(($contents = stream_get_contents($stream)) === FALSE) throw IOException::notReadable('');
171 | $this->parse($contents,CFPropertyList::FORMAT_BINARY);
172 | }
173 |
174 | /**
175 | * Load a plist file.
176 | * Load and import a plist file.
177 | * @param string $file Path of PropertyList, defaults to {@link $file}
178 | * @param integer $format The format of the property list, see {@link FORMAT_XML}, {@link FORMAT_BINARY} and {@link FORMAT_AUTO}, defaults to {@link $format}
179 | * @return void
180 | * @throws PListException if file format version is not 00
181 | * @throws IOException if file could not be read
182 | * @throws DOMException if plist file could not be parsed properly
183 | * @uses $file if argument $file was not specified
184 | * @uses $value reset to empty array
185 | * @uses import() for importing the values
186 | */
187 | public function load($file=null,$format=null) {
188 | $file = $file ? $file : $this->file;
189 | $format = $format !== null ? $format : $this->format;
190 | $this->value = array();
191 |
192 | if(!is_readable($file)) throw IOException::notReadable($file);
193 |
194 | switch($format) {
195 | case CFPropertyList::FORMAT_BINARY:
196 | $this->readBinary($file);
197 | break;
198 | case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
199 | $fd = fopen($file,"rb");
200 | if(($magic_number = fread($fd,8)) === false) throw IOException::notReadable($file);
201 | fclose($fd);
202 |
203 | $filetype = substr($magic_number,0,6);
204 | $version = substr($magic_number,-2);
205 |
206 | if($filetype == "bplist") {
207 | if($version != "00") throw new PListException("Wrong file format version! Expected 00, got $version!");
208 | $this->readBinary($file);
209 | break;
210 | }
211 | // else: xml format, break not neccessary
212 | case CFPropertyList::FORMAT_XML:
213 | $doc = new DOMDocument();
214 | if(!$doc->load($file)) throw new DOMException();
215 | $this->import($doc->documentElement, $this);
216 | break;
217 | }
218 | }
219 |
220 | /**
221 | * Parse a plist string.
222 | * Parse and import a plist string.
223 | * @param string $str String containing the PropertyList, defaults to {@link $content}
224 | * @param integer $format The format of the property list, see {@link FORMAT_XML}, {@link FORMAT_BINARY} and {@link FORMAT_AUTO}, defaults to {@link $format}
225 | * @return void
226 | * @throws PListException if file format version is not 00
227 | * @throws IOException if file could not be read
228 | * @throws DOMException if plist file could not be parsed properly
229 | * @uses $content if argument $str was not specified
230 | * @uses $value reset to empty array
231 | * @uses import() for importing the values
232 | */
233 | public function parse($str=NULL,$format=NULL) {
234 | $format = $format !== null ? $format : $this->format;
235 | $str = $str !== null ? $str : $this->content;
236 | $this->value = array();
237 |
238 | switch($format) {
239 | case CFPropertyList::FORMAT_BINARY:
240 | $this->parseBinary($str);
241 | break;
242 | case CFPropertyList::FORMAT_AUTO: // what we now do is ugly, but neccessary to recognize the file format
243 | if(($magic_number = substr($str,0,8)) === false) throw IOException::notReadable("");
244 |
245 | $filetype = substr($magic_number,0,6);
246 | $version = substr($magic_number,-2);
247 |
248 | if($filetype == "bplist") {
249 | if($version != "00") throw new PListException("Wrong file format version! Expected 00, got $version!");
250 | $this->parseBinary($str);
251 | break;
252 | }
253 | // else: xml format, break not neccessary
254 | case CFPropertyList::FORMAT_XML:
255 | $doc = new DOMDocument();
256 | if(!$doc->loadXML($str)) throw new DOMException();
257 | $this->import($doc->documentElement, $this);
258 | break;
259 | }
260 | }
261 |
262 | /**
263 | * Convert a DOMNode into a CFType.
264 | * @param DOMNode $node Node to import children of
265 | * @param CFDictionary|CFArray|CFPropertyList $parent
266 | * @return void
267 | */
268 | protected function import(DOMNode $node, $parent) {
269 | // abort if there are no children
270 | if(!$node->childNodes->length) return;
271 |
272 | foreach($node->childNodes as $n) {
273 | // skip if we can't handle the element
274 | if(!isset(self::$types[$n->nodeName])) continue;
275 |
276 | $class = 'CFPropertyList\\'.self::$types[$n->nodeName];
277 | $key = null;
278 |
279 | // find previous if possible
280 | $ps = $n->previousSibling;
281 | while($ps && $ps->nodeName == '#text' && $ps->previousSibling) $ps = $ps->previousSibling;
282 |
283 | // read if possible
284 | if($ps && $ps->nodeName == 'key') $key = $ps->firstChild->nodeValue;
285 |
286 | switch($n->nodeName) {
287 | case 'date':
288 | $value = new $class(CFDate::dateValue($n->nodeValue));
289 | break;
290 | case 'data':
291 | $value = new $class($n->nodeValue,true);
292 | break;
293 | case 'string':
294 | $value = new $class($n->nodeValue);
295 | break;
296 |
297 | case 'real':
298 | case 'integer':
299 | $value = new $class($n->nodeName == 'real' ? floatval($n->nodeValue) : intval($n->nodeValue));
300 | break;
301 |
302 | case 'true':
303 | case 'false':
304 | $value = new $class($n->nodeName == 'true');
305 | break;
306 |
307 | case 'array':
308 | case 'dict':
309 | $value = new $class();
310 | $this->import($n, $value);
311 | break;
312 | }
313 |
314 | // Dictionaries need a key
315 | if($parent instanceof CFDictionary) $parent->add($key, $value);
316 | // others don't
317 | else $parent->add($value);
318 | }
319 | }
320 |
321 | /**
322 | * Convert CFPropertyList to XML and save to file.
323 | * @param string $file Path of PropertyList, defaults to {@link $file}
324 | * @return void
325 | * @throws IOException if file could not be read
326 | * @uses $file if $file was not specified
327 | */
328 | public function saveXML($file) {
329 | $this->save($file,CFPropertyList::FORMAT_XML);
330 | }
331 |
332 | /**
333 | * Convert CFPropertyList to binary format (bplist00) and save to file.
334 | * @param string $file Path of PropertyList, defaults to {@link $file}
335 | * @return void
336 | * @throws IOException if file could not be read
337 | * @uses $file if $file was not specified
338 | */
339 | public function saveBinary($file) {
340 | $this->save($file,CFPropertyList::FORMAT_BINARY);
341 | }
342 |
343 | /**
344 | * Convert CFPropertyList to XML or binary and save to file.
345 | * @param string $file Path of PropertyList, defaults to {@link $file}
346 | * @param string $format Format of PropertyList, defaults to {@link $format}
347 | * @return void
348 | * @throws IOException if file could not be read
349 | * @throws PListException if evaluated $format is neither {@link FORMAT_XML} nor {@link FORMAL_BINARY}
350 | * @uses $file if $file was not specified
351 | * @uses $format if $format was not specified
352 | */
353 | public function save($file=null,$format=null) {
354 | $file = $file ? $file : $this->file;
355 | $format = $format ? $format : $this->format;
356 |
357 | if( !in_array( $format, array( self::FORMAT_BINARY, self::FORMAT_XML ) ) )
358 | throw new PListException( "format {$format} is not supported, use CFPropertyList::FORMAT_BINARY or CFPropertyList::FORMAT_XML" );
359 |
360 | if(!file_exists($file)) {
361 | // dirname("file.xml") == "" and is treated as the current working directory
362 | if(!is_writable(dirname($file))) throw IOException::notWritable($file);
363 | }
364 | else if(!is_writable($file)) throw IOException::notWritable($file);
365 |
366 | $content = $format == self::FORMAT_BINARY ? $this->toBinary() : $this->toXML();
367 |
368 | $fh = fopen($file, 'wb');
369 | fwrite($fh,$content);
370 | fclose($fh);
371 | }
372 |
373 | /**
374 | * Convert CFPropertyList to XML
375 | * @param bool $formatted Print plist formatted (i.e. with newlines and whitespace indention) if true; defaults to false
376 | * @return string The XML content
377 | */
378 | public function toXML($formatted=false) {
379 | $domimpl = new DOMImplementation();
380 | //
381 | $dtd = $domimpl->createDocumentType('plist', '-//Apple Computer//DTD PLIST 1.0//EN', 'http://www.apple.com/DTDs/PropertyList-1.0.dtd');
382 | $doc = $domimpl->createDocument(null, "plist", $dtd);
383 | $doc->encoding = "UTF-8";
384 |
385 | // format output
386 | if($formatted) {
387 | $doc->formatOutput = true;
388 | $doc->preserveWhiteSpace = true;
389 | }
390 |
391 | // get documentElement and set attribs
392 | $plist = $doc->documentElement;
393 | $plist->setAttribute('version', '1.0');
394 |
395 | // add PropertyList's children
396 | $plist->appendChild($this->getValue(true)->toXML($doc));
397 |
398 | return $doc->saveXML();
399 | }
400 |
401 |
402 | /************************************************************************************************
403 | * M A N I P U L A T I O N
404 | ************************************************************************************************/
405 |
406 | /**
407 | * Add CFType to collection.
408 | * @param CFType $value CFType to add to collection
409 | * @return void
410 | * @uses $value for adding $value
411 | */
412 | public function add(CFType $value=null) {
413 | // anything but CFType is null, null is an empty string - sad but true
414 | if( !$value )
415 | $value = new CFString();
416 |
417 | $this->value[] = $value;
418 | }
419 |
420 | /**
421 | * Get CFType from collection.
422 | * @param integer $key Key of CFType to retrieve from collection
423 | * @return CFType CFType found at $key, null else
424 | * @uses $value for retrieving CFType of $key
425 | */
426 | public function get($key) {
427 | if(isset($this->value[$key])) return $this->value[$key];
428 | return null;
429 | }
430 |
431 | /**
432 | * Generic getter (magic)
433 | *
434 | * @param integer $key Key of CFType to retrieve from collection
435 | * @return CFType CFType found at $key, null else
436 | * @author Sean Coates
437 | * @link http://php.net/oop5.overloading
438 | */
439 | public function __get($key) {
440 | return $this->get($key);
441 | }
442 |
443 | /**
444 | * Remove CFType from collection.
445 | * @param integer $key Key of CFType to removes from collection
446 | * @return CFType removed CFType, null else
447 | * @uses $value for removing CFType of $key
448 | */
449 | public function del($key) {
450 | if(isset($this->value[$key])) {
451 | $t = $this->value[$key];
452 | unset($this->value[$key]);
453 | return $t;
454 | }
455 |
456 | return null;
457 | }
458 |
459 | /**
460 | * Empty the collection
461 | * @return array the removed CFTypes
462 | * @uses $value for removing CFType of $key
463 | */
464 | public function purge() {
465 | $t = $this->value;
466 | $this->value = array();
467 | return $t;
468 | }
469 |
470 | /**
471 | * Get first (and only) child, or complete collection.
472 | * @param string $cftype if set to true returned value will be CFArray instead of an array in case of a collection
473 | * @return CFType|array CFType or list of CFTypes known to the PropertyList
474 | * @uses $value for retrieving CFTypes
475 | */
476 | public function getValue($cftype=false) {
477 | if(count($this->value) === 1) {
478 | $t = array_values( $this->value );
479 | return $t[0];
480 | }
481 | if($cftype) {
482 | $t = new CFArray();
483 | foreach( $this->value as $value ) {
484 | if( $value instanceof CFType ) $t->add($value);
485 | }
486 | return $t;
487 | }
488 | return $this->value;
489 | }
490 |
491 | /**
492 | * Create CFType-structure from guessing the data-types.
493 | * The functionality has been moved to the more flexible {@link CFTypeDetector} facility.
494 | * @param mixed $value Value to convert to CFType
495 | * @param array $options Configuration for casting values [autoDictionary, suppressExceptions, objectToArrayMethod, castNumericStrings]
496 | * @return CFType CFType based on guessed type
497 | * @uses CFTypeDetector for actual type detection
498 | * @deprecated
499 | */
500 | public static function guess($value, $options=array()) {
501 | static $t = null;
502 | if( $t === null )
503 | $t = new CFTypeDetector( $options );
504 |
505 | return $t->toCFType( $value );
506 | }
507 |
508 |
509 | /************************************************************************************************
510 | * S E R I A L I Z I N G
511 | ************************************************************************************************/
512 |
513 | /**
514 | * Get PropertyList as array.
515 | * @return mixed primitive value of first (and only) CFType, or array of primitive values of collection
516 | * @uses $value for retrieving CFTypes
517 | */
518 | public function toArray() {
519 | $a = array();
520 | foreach($this->value as $value) $a[] = $value->toArray();
521 | if(count($a) === 1) return $a[0];
522 |
523 | return $a;
524 | }
525 |
526 |
527 | /************************************************************************************************
528 | * I T E R A T O R I N T E R F A C E
529 | ************************************************************************************************/
530 |
531 | /**
532 | * Rewind {@link $iteratorPosition} to first position (being 0)
533 | * @link http://php.net/manual/en/iterator.rewind.php
534 | * @return void
535 | * @uses $iteratorPosition set to 0
536 | * @uses $iteratorKeys store keys of {@link $value}
537 | */
538 | public function rewind() {
539 | $this->iteratorPosition = 0;
540 | $this->iteratorKeys = array_keys($this->value);
541 | }
542 |
543 | /**
544 | * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
545 | * @link http://php.net/manual/en/iterator.current.php
546 | * @return CFType current Item
547 | * @uses $iteratorPosition identify current key
548 | * @uses $iteratorKeys identify current value
549 | */
550 | public function current() {
551 | return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
552 | }
553 |
554 | /**
555 | * Get Iterator's current key identified by {@link $iteratorPosition}
556 | * @link http://php.net/manual/en/iterator.key.php
557 | * @return string key of the current Item
558 | * @uses $iteratorPosition identify current key
559 | * @uses $iteratorKeys identify current value
560 | */
561 | public function key() {
562 | return $this->iteratorKeys[$this->iteratorPosition];
563 | }
564 |
565 | /**
566 | * Increment {@link $iteratorPosition} to address next {@see CFType}
567 | * @link http://php.net/manual/en/iterator.next.php
568 | * @return void
569 | * @uses $iteratorPosition increment by 1
570 | */
571 | public function next() {
572 | $this->iteratorPosition++;
573 | }
574 |
575 | /**
576 | * Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
577 | * @link http://php.net/manual/en/iterator.valid.php
578 | * @return boolean true if current position is valid, false else
579 | * @uses $iteratorPosition test if within {@link $iteratorKeys}
580 | * @uses $iteratorPosition test if within {@link $value}
581 | */
582 | public function valid() {
583 | return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
584 | }
585 |
586 | }
587 |
588 | # eof
--------------------------------------------------------------------------------
/src/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/CFType.php:
--------------------------------------------------------------------------------
1 |
6 | * @author Christian Kruse
7 | * @package plist
8 | * @subpackage plist.types
9 | * @version $Id$
10 | */
11 | namespace CFPropertyList;
12 | use \DOMDocument, \Iterator, \ArrayAccess;
13 |
14 | /**
15 | * Base-Class of all CFTypes used by CFPropertyList
16 | * @author Rodney Rehm
17 | * @author Christian Kruse
18 | * @package plist
19 | * @subpackage plist.types
20 | * @version $Id$
21 | * @example example-create-01.php Using the CFPropertyList API
22 | * @example example-create-02.php Using CFPropertyList::guess()
23 | * @example example-create-03.php Using CFPropertyList::guess() with {@link CFDate} and {@link CFData}
24 | */
25 | abstract class CFType {
26 | /**
27 | * CFType nodes
28 | * @var array
29 | */
30 | protected $value = null;
31 |
32 | /**
33 | * Create new CFType.
34 | * @param mixed $value Value of CFType
35 | */
36 | public function __construct($value=null) {
37 | $this->setValue($value);
38 | }
39 |
40 | /************************************************************************************************
41 | * M A G I C P R O P E R T I E S
42 | ************************************************************************************************/
43 |
44 | /**
45 | * Get the CFType's value
46 | * @return mixed CFType's value
47 | */
48 | public function getValue() {
49 | return $this->value;
50 | }
51 |
52 | /**
53 | * Set the CFType's value
54 | * @return void
55 | */
56 | public function setValue($value) {
57 | $this->value = $value;
58 | }
59 |
60 | /************************************************************************************************
61 | * S E R I A L I Z I N G
62 | ************************************************************************************************/
63 |
64 | /**
65 | * Get XML-Node.
66 | * @param DOMDocument $doc DOMDocument to create DOMNode in
67 | * @param string $nodeName Name of element to create
68 | * @return DOMNode Node created based on CType
69 | * @uses $value as nodeValue
70 | */
71 | public function toXML(DOMDocument $doc, $nodeName) {
72 | $node = $doc->createElement($nodeName);
73 |
74 | if($this->value != '') {
75 | $text = $doc->createTextNode($this->value);
76 | $node->appendChild($text);
77 | }
78 |
79 | return $node;
80 | }
81 |
82 | /**
83 | * convert value to binary representation
84 | * @param CFBinaryPropertyList The binary property list object
85 | * @return The offset in the object table
86 | */
87 | public abstract function toBinary(CFBinaryPropertyList &$bplist);
88 |
89 | /**
90 | * Get CFType's value.
91 | * @return mixed primitive value
92 | * @uses $value for retrieving primitive of CFType
93 | */
94 | public function toArray() {
95 | return $this->getValue();
96 | }
97 |
98 | }
99 |
100 | /**
101 | * String Type of CFPropertyList
102 | * @author Rodney Rehm
103 | * @author Christian Kruse
104 | * @package plist
105 | * @subpackage plist.types
106 | */
107 | class CFString extends CFType {
108 | /**
109 | * Get XML-Node.
110 | * @param DOMDocument $doc DOMDocument to create DOMNode in
111 | * @param string $nodeName For compatibility reasons; just ignore it
112 | * @return DOMNode <string>-Element
113 | */
114 | public function toXML(DOMDocument $doc,$nodeName="") {
115 | return parent::toXML($doc, 'string');
116 | }
117 |
118 | /**
119 | * convert value to binary representation
120 | * @param CFBinaryPropertyList The binary property list object
121 | * @return The offset in the object table
122 | */
123 | public function toBinary(CFBinaryPropertyList &$bplist) {
124 | return $bplist->stringToBinary($this->value);
125 | }
126 | }
127 |
128 | /**
129 | * Number Type of CFPropertyList
130 | * @author Rodney Rehm
131 | * @author Christian Kruse
132 | * @package plist
133 | * @subpackage plist.types
134 | */
135 | class CFNumber extends CFType {
136 | /**
137 | * Get XML-Node.
138 | * Returns <real> if $value is a float, <integer> if $value is an integer.
139 | * @param DOMDocument $doc DOMDocument to create DOMNode in
140 | * @param string $nodeName For compatibility reasons; just ignore it
141 | * @return DOMNode <real> or <integer>-Element
142 | */
143 | public function toXML(DOMDocument $doc,$nodeName="") {
144 | $ret = 'real';
145 | if(intval($this->value) == $this->value && !is_float($this->value) && strpos($this->value,'.') === false) {
146 | $this->value = intval($this->value);
147 | $ret = 'integer';
148 | }
149 | return parent::toXML($doc, $ret);
150 | }
151 |
152 | /**
153 | * convert value to binary representation
154 | * @param CFBinaryPropertyList The binary property list object
155 | * @return The offset in the object table
156 | */
157 | public function toBinary(CFBinaryPropertyList &$bplist) {
158 | return $bplist->numToBinary($this->value);
159 | }
160 | }
161 |
162 | /**
163 | * Date Type of CFPropertyList
164 | * Note: CFDate uses Unix timestamp (epoch) to store dates internally
165 | * @author Rodney Rehm
166 | * @author Christian Kruse
167 | * @package plist
168 | * @subpackage plist.types
169 | */
170 | class CFDate extends CFType {
171 | const TIMESTAMP_APPLE = 0;
172 | const TIMESTAMP_UNIX = 1;
173 | const DATE_DIFF_APPLE_UNIX = 978307200;
174 |
175 | /**
176 | * Create new Date CFType.
177 | * @param integer $value timestamp to set
178 | * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_APPLE}
179 | * @uses setValue() to convert the timestamp
180 | */
181 | function __construct($value,$format=CFDate::TIMESTAMP_UNIX) {
182 | $this->setValue($value,$format);
183 | }
184 |
185 | /**
186 | * Set the Date CFType's value.
187 | * @param integer $value timestamp to set
188 | * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
189 | * @return void
190 | * @uses TIMESTAMP_APPLE to determine timestamp type
191 | * @uses TIMESTAMP_UNIX to determine timestamp type
192 | * @uses DATE_DIFF_APPLE_UNIX to convert Apple-timestamp to Unix-timestamp
193 | */
194 | function setValue($value,$format=CFDate::TIMESTAMP_UNIX) {
195 | if($format == CFDate::TIMESTAMP_UNIX) $this->value = $value;
196 | else $this->value = $value + CFDate::DATE_DIFF_APPLE_UNIX;
197 | }
198 |
199 | /**
200 | * Get the Date CFType's value.
201 | * @param integer $format format the timestamp is specified in, use {@link TIMESTAMP_APPLE} or {@link TIMESTAMP_UNIX}, defaults to {@link TIMESTAMP_UNIX}
202 | * @return integer Unix timestamp
203 | * @uses TIMESTAMP_APPLE to determine timestamp type
204 | * @uses TIMESTAMP_UNIX to determine timestamp type
205 | * @uses DATE_DIFF_APPLE_UNIX to convert Unix-timestamp to Apple-timestamp
206 | */
207 | function getValue($format=CFDate::TIMESTAMP_UNIX) {
208 | if($format == CFDate::TIMESTAMP_UNIX) return $this->value;
209 | else return $this->value - CFDate::DATE_DIFF_APPLE_UNIX;
210 | }
211 |
212 | /**
213 | * Get XML-Node.
214 | * @param DOMDocument $doc DOMDocument to create DOMNode in
215 | * @param string $nodeName For compatibility reasons; just ignore it
216 | * @return DOMNode <date>-Element
217 | */
218 | public function toXML(DOMDocument $doc,$nodeName="") {
219 | $text = $doc->createTextNode(gmdate("Y-m-d\TH:i:s\Z",$this->getValue()));
220 | $node = $doc->createElement("date");
221 | $node->appendChild($text);
222 | return $node;
223 | }
224 |
225 | /**
226 | * convert value to binary representation
227 | * @param CFBinaryPropertyList The binary property list object
228 | * @return The offset in the object table
229 | */
230 | public function toBinary(CFBinaryPropertyList &$bplist) {
231 | return $bplist->dateToBinary($this->value);
232 | }
233 |
234 | /**
235 | * Create a UNIX timestamp from a PList date string
236 | * @param string $val The date string (e.g. "2009-05-13T20:23:43Z")
237 | * @return integer The UNIX timestamp
238 | * @throws PListException when encountering an unknown date string format
239 | */
240 | public static function dateValue($val) {
241 | //2009-05-13T20:23:43Z
242 | if(!preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/',$val,$matches)) throw new PListException("Unknown date format: $val");
243 | return gmmktime($matches[4],$matches[5],$matches[6],$matches[2],$matches[3],$matches[1]);
244 | }
245 | }
246 |
247 | /**
248 | * Boolean Type of CFPropertyList
249 | * @author Rodney Rehm
250 | * @author Christian Kruse
251 | * @package plist
252 | * @subpackage plist.types
253 | */
254 | class CFBoolean extends CFType {
255 | /**
256 | * Get XML-Node.
257 | * Returns <true> if $value is a true, <false> if $value is false.
258 | * @param DOMDocument $doc DOMDocument to create DOMNode in
259 | * @param string $nodeName For compatibility reasons; just ignore it
260 | * @return DOMNode <true> or <false>-Element
261 | */
262 | public function toXML(DOMDocument $doc,$nodeName="") {
263 | return $doc->createElement($this->value ? 'true' : 'false');
264 | }
265 |
266 | /**
267 | * convert value to binary representation
268 | * @param CFBinaryPropertyList The binary property list object
269 | * @return The offset in the object table
270 | */
271 | public function toBinary(CFBinaryPropertyList &$bplist) {
272 | return $bplist->boolToBinary($this->value);
273 | }
274 |
275 | }
276 |
277 | /**
278 | * Data Type of CFPropertyList
279 | * Note: Binary data is base64-encoded.
280 | * @author Rodney Rehm
281 | * @author Christian Kruse
282 | * @package plist
283 | * @subpackage plist.types
284 | */
285 | class CFData extends CFType {
286 | /**
287 | * Create new Data CFType
288 | * @param string $value data to be contained by new object
289 | * @param boolean $already_coded if true $value will not be base64-encoded, defaults to false
290 | */
291 | public function __construct($value=null,$already_coded=false) {
292 | if($already_coded) $this->value = $value;
293 | else $this->setValue($value);
294 | }
295 |
296 | /**
297 | * Set the CFType's value and base64-encode it.
298 | * Note: looks like base64_encode has troubles with UTF-8 encoded strings
299 | * @return void
300 | */
301 | public function setValue($value) {
302 | //if(function_exists('mb_check_encoding') && mb_check_encoding($value, 'UTF-8')) $value = utf8_decode($value);
303 | $this->value = base64_encode($value);
304 | }
305 |
306 | /**
307 | * Get base64 encoded data
308 | * @return string The base64 encoded data value
309 | */
310 | public function getCodedValue() {
311 | return $this->value;
312 | }
313 |
314 | /**
315 | * Get the base64-decoded CFType's value.
316 | * @return mixed CFType's value
317 | */
318 | public function getValue() {
319 | return base64_decode($this->value);
320 | }
321 |
322 | /**
323 | * Get XML-Node.
324 | * @param DOMDocument $doc DOMDocument to create DOMNode in
325 | * @param string $nodeName For compatibility reasons; just ignore it
326 | * @return DOMNode <data>-Element
327 | */
328 | public function toXML(DOMDocument $doc,$nodeName="") {
329 | return parent::toXML($doc, 'data');
330 | }
331 |
332 | /**
333 | * convert value to binary representation
334 | * @param CFBinaryPropertyList The binary property list object
335 | * @return The offset in the object table
336 | */
337 | public function toBinary(CFBinaryPropertyList &$bplist) {
338 | return $bplist->dataToBinary($this->getValue());
339 | }
340 | }
341 |
342 | /**
343 | * Array Type of CFPropertyList
344 | * @author Rodney Rehm
345 | * @author Christian Kruse
346 | * @package plist
347 | * @subpackage plist.types
348 | */
349 | class CFArray extends CFType implements Iterator, ArrayAccess {
350 | /**
351 | * Position of iterator {@link http://php.net/manual/en/class.iterator.php}
352 | * @var integer
353 | */
354 | protected $iteratorPosition = 0;
355 |
356 |
357 | /**
358 | * Create new CFType.
359 | * @param array $value Value of CFType
360 | */
361 | public function __construct($value=array()) {
362 | $this->value = $value;
363 | }
364 |
365 | /**
366 | * Set the CFType's value
367 | * Note: this dummy does nothing
368 | * @return void
369 | */
370 | public function setValue($value) {
371 | }
372 |
373 | /**
374 | * Add CFType to collection.
375 | * @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString}
376 | * @return void
377 | * @uses $value for adding $value
378 | */
379 | public function add(CFType $value=null) {
380 | // anything but CFType is null, null is an empty string - sad but true
381 | if( !$value )
382 | $value = new CFString();
383 |
384 | $this->value[] = $value;
385 | }
386 |
387 | /**
388 | * Get CFType from collection.
389 | * @param integer $key Key of CFType to retrieve from collection
390 | * @return CFType CFType found at $key, null else
391 | * @uses $value for retrieving CFType of $key
392 | */
393 | public function get($key) {
394 | if(isset($this->value[$key])) return $this->value[$key];
395 | return null;
396 | }
397 |
398 | /**
399 | * Remove CFType from collection.
400 | * @param integer $key Key of CFType to removes from collection
401 | * @return CFType removed CFType, null else
402 | * @uses $value for removing CFType of $key
403 | */
404 | public function del($key) {
405 | if(isset($this->value[$key])) unset($this->value[$key]);
406 | }
407 |
408 |
409 | /************************************************************************************************
410 | * S E R I A L I Z I N G
411 | ************************************************************************************************/
412 |
413 | /**
414 | * Get XML-Node.
415 | * @param DOMDocument $doc DOMDocument to create DOMNode in
416 | * @param string $nodeName For compatibility reasons; just ignore it
417 | * @return DOMNode <array>-Element
418 | */
419 | public function toXML(DOMDocument $doc,$nodeName="") {
420 | $node = $doc->createElement('array');
421 |
422 | foreach($this->value as $value) $node->appendChild($value->toXML($doc));
423 | return $node;
424 | }
425 |
426 | /**
427 | * convert value to binary representation
428 | * @param CFBinaryPropertyList The binary property list object
429 | * @return The offset in the object table
430 | */
431 | public function toBinary(CFBinaryPropertyList &$bplist) {
432 | return $bplist->arrayToBinary($this);
433 | }
434 |
435 | /**
436 | * Get CFType's value.
437 | * @return array primitive value
438 | * @uses $value for retrieving primitive of CFType
439 | */
440 | public function toArray() {
441 | $a = array();
442 | foreach($this->value as $value) $a[] = $value->toArray();
443 | return $a;
444 | }
445 |
446 |
447 | /************************************************************************************************
448 | * I T E R A T O R I N T E R F A C E
449 | ************************************************************************************************/
450 |
451 | /**
452 | * Rewind {@link $iteratorPosition} to first position (being 0)
453 | * @link http://php.net/manual/en/iterator.rewind.php
454 | * @return void
455 | * @uses $iteratorPosition set to 0
456 | */
457 | public function rewind() {
458 | $this->iteratorPosition = 0;
459 | }
460 |
461 | /**
462 | * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
463 | * @link http://php.net/manual/en/iterator.current.php
464 | * @return CFType current Item
465 | * @uses $iteratorPosition identify current key
466 | */
467 | public function current() {
468 | return $this->value[$this->iteratorPosition];
469 | }
470 |
471 | /**
472 | * Get Iterator's current key identified by {@link $iteratorPosition}
473 | * @link http://php.net/manual/en/iterator.key.php
474 | * @return string key of the current Item
475 | * @uses $iteratorPosition identify current key
476 | */
477 | public function key() {
478 | return $this->iteratorPosition;
479 | }
480 |
481 | /**
482 | * Increment {@link $iteratorPosition} to address next {@see CFType}
483 | * @link http://php.net/manual/en/iterator.next.php
484 | * @return void
485 | * @uses $iteratorPosition increment by 1
486 | */
487 | public function next() {
488 | $this->iteratorPosition++;
489 | }
490 |
491 | /**
492 | * Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
493 | * @link http://php.net/manual/en/iterator.valid.php
494 | * @return boolean true if current position is valid, false else
495 | * @uses $iteratorPosition test if within {@link $iteratorKeys}
496 | * @uses $iteratorPosition test if within {@link $value}
497 | */
498 | public function valid() {
499 | return isset($this->value[$this->iteratorPosition]);
500 | }
501 |
502 | /************************************************************************************************
503 | * ArrayAccess I N T E R F A C E
504 | ************************************************************************************************/
505 |
506 | /**
507 | * Determine if the array's key exists
508 | * @param string $key the key to check
509 | * @return bool true if the offset exists, false if not
510 | * @link http://php.net/manual/en/arrayaccess.offsetexists.php
511 | * @uses $value to check if $key exists
512 | * @author Sean Coates
513 | */
514 | public function offsetExists($key) {
515 | return isset($this->value[$key]);
516 | }
517 |
518 | /**
519 | * Fetch a specific key from the CFArray
520 | * @param string $key the key to check
521 | * @return mixed the value associated with the key; null if the key is not found
522 | * @link http://php.net/manual/en/arrayaccess.offsetget.php
523 | * @uses get() to get the key's value
524 | * @author Sean Coates
525 | */
526 | public function offsetGet($key) {
527 | return $this->get($key);
528 | }
529 |
530 | /**
531 | * Set a value in the array
532 | * @param string $key the key to set
533 | * @param string $value the value to set
534 | * @return void
535 | * @link http://php.net/manual/en/arrayaccess.offsetset.php
536 | * @uses setValue() to set the key's new value
537 | * @author Sean Coates
538 | */
539 | public function offsetSet($key, $value) {
540 | return $this->setValue($value);
541 | }
542 |
543 | /**
544 | * Unsets a value in the array
545 | * Note: this dummy does nothing
546 | * @param string $key the key to set
547 | * @return void
548 | * @link http://php.net/manual/en/arrayaccess.offsetunset.php
549 | * @author Sean Coates
550 | */
551 | public function offsetUnset($key) {
552 |
553 | }
554 |
555 |
556 | }
557 |
558 | /**
559 | * Array Type of CFPropertyList
560 | * @author Rodney Rehm
561 | * @author Christian Kruse
562 | * @package plist
563 | * @subpackage plist.types
564 | */
565 | class CFDictionary extends CFType implements Iterator {
566 | /**
567 | * Position of iterator {@link http://php.net/manual/en/class.iterator.php}
568 | * @var integer
569 | */
570 | protected $iteratorPosition = 0;
571 |
572 | /**
573 | * List of Keys for numerical iterator access {@link http://php.net/manual/en/class.iterator.php}
574 | * @var array
575 | */
576 | protected $iteratorKeys = null;
577 |
578 |
579 | /**
580 | * Create new CFType.
581 | * @param array $value Value of CFType
582 | */
583 | public function __construct($value=array()) {
584 | $this->value = $value;
585 | }
586 |
587 | /**
588 | * Set the CFType's value
589 | * Note: this dummy does nothing
590 | * @return void
591 | */
592 | public function setValue($value) {
593 | }
594 |
595 | /**
596 | * Add CFType to collection.
597 | * @param string $key Key to add to collection
598 | * @param CFType $value CFType to add to collection, defaults to null which results in an empty {@link CFString}
599 | * @return void
600 | * @uses $value for adding $key $value pair
601 | */
602 | public function add($key, CFType $value=null) {
603 | // anything but CFType is null, null is an empty string - sad but true
604 | if( !$value )
605 | $value = new CFString();
606 |
607 | $this->value[$key] = $value;
608 | }
609 |
610 | /**
611 | * Get CFType from collection.
612 | * @param string $key Key of CFType to retrieve from collection
613 | * @return CFType CFType found at $key, null else
614 | * @uses $value for retrieving CFType of $key
615 | */
616 | public function get($key) {
617 | if(isset($this->value[$key])) return $this->value[$key];
618 | return null;
619 | }
620 |
621 | /**
622 | * Generic getter (magic)
623 | * @param integer $key Key of CFType to retrieve from collection
624 | * @return CFType CFType found at $key, null else
625 | * @link http://php.net/oop5.overloading
626 | * @uses get() to retrieve the key's value
627 | * @author Sean Coates
628 | */
629 | public function __get($key) {
630 | return $this->get($key);
631 | }
632 |
633 | /**
634 | * Remove CFType from collection.
635 | * @param string $key Key of CFType to removes from collection
636 | * @return CFType removed CFType, null else
637 | * @uses $value for removing CFType of $key
638 | */
639 | public function del($key) {
640 | if(isset($this->value[$key])) unset($this->value[$key]);
641 | }
642 |
643 |
644 | /************************************************************************************************
645 | * S E R I A L I Z I N G
646 | ************************************************************************************************/
647 |
648 | /**
649 | * Get XML-Node.
650 | * @param DOMDocument $doc DOMDocument to create DOMNode in
651 | * @param string $nodeName For compatibility reasons; just ignore it
652 | * @return DOMNode <dict>-Element
653 | */
654 | public function toXML(DOMDocument $doc,$nodeName="") {
655 | $node = $doc->createElement('dict');
656 |
657 | foreach($this->value as $key => $value) {
658 | $node->appendChild($doc->createElement('key', $key));
659 | $node->appendChild($value->toXML($doc));
660 | }
661 |
662 | return $node;
663 | }
664 |
665 | /**
666 | * convert value to binary representation
667 | * @param CFBinaryPropertyList The binary property list object
668 | * @return The offset in the object table
669 | */
670 | public function toBinary(CFBinaryPropertyList &$bplist) {
671 | return $bplist->dictToBinary($this);
672 | }
673 |
674 | /**
675 | * Get CFType's value.
676 | * @return array primitive value
677 | * @uses $value for retrieving primitive of CFType
678 | */
679 | public function toArray() {
680 | $a = array();
681 |
682 | foreach($this->value as $key => $value) $a[$key] = $value->toArray();
683 | return $a;
684 | }
685 |
686 |
687 | /************************************************************************************************
688 | * I T E R A T O R I N T E R F A C E
689 | ************************************************************************************************/
690 |
691 | /**
692 | * Rewind {@link $iteratorPosition} to first position (being 0)
693 | * @link http://php.net/manual/en/iterator.rewind.php
694 | * @return void
695 | * @uses $iteratorPosition set to 0
696 | * @uses $iteratorKeys store keys of {@link $value}
697 | */
698 | public function rewind() {
699 | $this->iteratorPosition = 0;
700 | $this->iteratorKeys = array_keys($this->value);
701 | }
702 |
703 | /**
704 | * Get Iterator's current {@link CFType} identified by {@link $iteratorPosition}
705 | * @link http://php.net/manual/en/iterator.current.php
706 | * @return CFType current Item
707 | * @uses $iteratorPosition identify current key
708 | * @uses $iteratorKeys identify current value
709 | */
710 | public function current() {
711 | return $this->value[$this->iteratorKeys[$this->iteratorPosition]];
712 | }
713 |
714 | /**
715 | * Get Iterator's current key identified by {@link $iteratorPosition}
716 | * @link http://php.net/manual/en/iterator.key.php
717 | * @return string key of the current Item
718 | * @uses $iteratorPosition identify current key
719 | * @uses $iteratorKeys identify current value
720 | */
721 | public function key() {
722 | return $this->iteratorKeys[$this->iteratorPosition];
723 | }
724 |
725 | /**
726 | * Increment {@link $iteratorPosition} to address next {@see CFType}
727 | * @link http://php.net/manual/en/iterator.next.php
728 | * @return void
729 | * @uses $iteratorPosition increment by 1
730 | */
731 | public function next() {
732 | $this->iteratorPosition++;
733 | }
734 |
735 | /**
736 | * Test if {@link $iteratorPosition} addresses a valid element of {@link $value}
737 | * @link http://php.net/manual/en/iterator.valid.php
738 | * @return boolean true if current position is valid, false else
739 | * @uses $iteratorPosition test if within {@link $iteratorKeys}
740 | * @uses $iteratorPosition test if within {@link $value}
741 | */
742 | public function valid() {
743 | return isset($this->iteratorKeys[$this->iteratorPosition]) && isset($this->value[$this->iteratorKeys[$this->iteratorPosition]]);
744 | }
745 |
746 | }
747 |
748 | # eof
--------------------------------------------------------------------------------