├── src ├── c.png ├── cpp.png ├── css.png ├── d3.png ├── doc.png ├── dom.png ├── git.png ├── go.png ├── lua.png ├── npm.png ├── php.png ├── q.png ├── svg.png ├── vue.png ├── yii.png ├── bower.png ├── chai.png ├── chef.png ├── dojo.png ├── ember.png ├── fish.png ├── flow.png ├── gcc~4.png ├── gcc~5.png ├── grunt.png ├── haxe.png ├── html.png ├── http.png ├── icon.png ├── less.png ├── love.png ├── mocha.png ├── nginx.png ├── node.png ├── perl.png ├── ramda.png ├── rdoc.png ├── react.png ├── redis.png ├── redux.png ├── rust.png ├── sass.png ├── sinon.png ├── angular.png ├── ansible.png ├── apache.png ├── backbone.png ├── cakephp.png ├── clojure.png ├── cordova.png ├── crystal.png ├── docker.png ├── drupal.png ├── elixir.png ├── erlang.png ├── express.png ├── haskell.png ├── jquery.png ├── jqueryui.png ├── knockout.png ├── kotlin.png ├── laravel.png ├── lodash.png ├── lodash~3.png ├── lodash~4.png ├── markdown.png ├── maxcdn.png ├── meteor.png ├── minitest.png ├── moment.png ├── mongoose.png ├── nokogiri.png ├── padrino.png ├── phalcon.png ├── phaser.png ├── phpunit.png ├── postgres.png ├── python.png ├── ruby~2.2.png ├── ruby~2.3.png ├── socketio.png ├── sphinx.png ├── tcl_tk.png ├── vagrant.png ├── webpack.png ├── yii~1.1.png ├── yii~2.0.png ├── angularjs.png ├── apache_pig.png ├── bootstrap.png ├── dom_events.png ├── gcc~4_cpp.png ├── gcc~5_cpp.png ├── influxdata.png ├── javascript.png ├── marionette.png ├── modernizr.png ├── node~4_lts.png ├── postgresql.png ├── rails~4.1.png ├── rails~4.2.png ├── rails~5.0.png ├── requirejs.png ├── rethinkdb.png ├── tensorflow.png ├── typescript.png ├── underscore.png ├── xslt_xpath.png ├── angularjs~1.2.png ├── angularjs~1.3.png ├── angularjs~1.4.png ├── angularjs~1.5.png ├── coffeescript.png ├── gnu_fortran~4.png ├── gnu_fortran~5.png ├── gnu_fortran~6.png ├── jquerymobile.png ├── laravel~5.1.png ├── laravel~5.2.png ├── react_native.png ├── sphinx_simple.png ├── symfony~2.7.png ├── symfony~2.8.png ├── symfony~3.0.png ├── codeigniter~3.0.png ├── support_tables.png ├── nginx_lua_module.png ├── angular~4_typescript.png ├── angular~2.0_typescript.png ├── scripts │ ├── vendor │ │ ├── rodneyrehm │ │ │ └── plist │ │ │ │ ├── .gitignore │ │ │ │ ├── tests │ │ │ │ ├── binary-data.plist │ │ │ │ ├── xml-data.plist │ │ │ │ ├── WriteXMLTest.php │ │ │ │ ├── WriteBinaryTest.php │ │ │ │ ├── BinaryParseTest.php │ │ │ │ └── ParseXMLTest.php │ │ │ │ ├── examples │ │ │ │ ├── sample.binary.plist │ │ │ │ ├── sample.xml.plist │ │ │ │ ├── example-read-01.php │ │ │ │ ├── example-read-03.php │ │ │ │ ├── example-modify-01.php │ │ │ │ ├── example-read-02.php │ │ │ │ ├── example-read-05.php │ │ │ │ ├── example-read-04.php │ │ │ │ ├── example-create-03.php │ │ │ │ ├── example-create-02.php │ │ │ │ ├── example-create-01.php │ │ │ │ └── example-create-04.php │ │ │ │ ├── build.sh │ │ │ │ ├── classes │ │ │ │ └── CFPropertyList │ │ │ │ │ ├── PListException.php │ │ │ │ │ ├── IOException.php │ │ │ │ │ ├── CFTypeDetector.php │ │ │ │ │ ├── CFPropertyList.php │ │ │ │ │ └── CFType.php │ │ │ │ ├── composer.json │ │ │ │ ├── LICENSE │ │ │ │ └── README.md │ │ ├── composer │ │ │ ├── autoload_psr4.php │ │ │ ├── autoload_classmap.php │ │ │ ├── autoload_namespaces.php │ │ │ ├── autoload_real.php │ │ │ ├── installed.json │ │ │ └── ClassLoader.php │ │ └── autoload.php │ ├── composer.json │ ├── composer.lock │ ├── devdocs.php │ ├── conf.php │ └── workflows.php └── info.plist ├── .gitignore ├── README.md └── LICENSE /src/c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/c.png -------------------------------------------------------------------------------- /src/cpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/cpp.png -------------------------------------------------------------------------------- /src/css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/css.png -------------------------------------------------------------------------------- /src/d3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/d3.png -------------------------------------------------------------------------------- /src/doc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/doc.png -------------------------------------------------------------------------------- /src/dom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/dom.png -------------------------------------------------------------------------------- /src/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/git.png -------------------------------------------------------------------------------- /src/go.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/go.png -------------------------------------------------------------------------------- /src/lua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/lua.png -------------------------------------------------------------------------------- /src/npm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/npm.png -------------------------------------------------------------------------------- /src/php.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/php.png -------------------------------------------------------------------------------- /src/q.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/q.png -------------------------------------------------------------------------------- /src/svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/svg.png -------------------------------------------------------------------------------- /src/vue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/vue.png -------------------------------------------------------------------------------- /src/yii.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/yii.png -------------------------------------------------------------------------------- /src/bower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/bower.png -------------------------------------------------------------------------------- /src/chai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/chai.png -------------------------------------------------------------------------------- /src/chef.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/chef.png -------------------------------------------------------------------------------- /src/dojo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/dojo.png -------------------------------------------------------------------------------- /src/ember.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/ember.png -------------------------------------------------------------------------------- /src/fish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/fish.png -------------------------------------------------------------------------------- /src/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/flow.png -------------------------------------------------------------------------------- /src/gcc~4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gcc~4.png -------------------------------------------------------------------------------- /src/gcc~5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gcc~5.png -------------------------------------------------------------------------------- /src/grunt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/grunt.png -------------------------------------------------------------------------------- /src/haxe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/haxe.png -------------------------------------------------------------------------------- /src/html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/html.png -------------------------------------------------------------------------------- /src/http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/http.png -------------------------------------------------------------------------------- /src/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/icon.png -------------------------------------------------------------------------------- /src/less.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/less.png -------------------------------------------------------------------------------- /src/love.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/love.png -------------------------------------------------------------------------------- /src/mocha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/mocha.png -------------------------------------------------------------------------------- /src/nginx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/nginx.png -------------------------------------------------------------------------------- /src/node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/node.png -------------------------------------------------------------------------------- /src/perl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/perl.png -------------------------------------------------------------------------------- /src/ramda.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/ramda.png -------------------------------------------------------------------------------- /src/rdoc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/rdoc.png -------------------------------------------------------------------------------- /src/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/react.png -------------------------------------------------------------------------------- /src/redis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/redis.png -------------------------------------------------------------------------------- /src/redux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/redux.png -------------------------------------------------------------------------------- /src/rust.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/rust.png -------------------------------------------------------------------------------- /src/sass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/sass.png -------------------------------------------------------------------------------- /src/sinon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/sinon.png -------------------------------------------------------------------------------- /src/angular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angular.png -------------------------------------------------------------------------------- /src/ansible.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/ansible.png -------------------------------------------------------------------------------- /src/apache.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/apache.png -------------------------------------------------------------------------------- /src/backbone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/backbone.png -------------------------------------------------------------------------------- /src/cakephp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/cakephp.png -------------------------------------------------------------------------------- /src/clojure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/clojure.png -------------------------------------------------------------------------------- /src/cordova.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/cordova.png -------------------------------------------------------------------------------- /src/crystal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/crystal.png -------------------------------------------------------------------------------- /src/docker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/docker.png -------------------------------------------------------------------------------- /src/drupal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/drupal.png -------------------------------------------------------------------------------- /src/elixir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/elixir.png -------------------------------------------------------------------------------- /src/erlang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/erlang.png -------------------------------------------------------------------------------- /src/express.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/express.png -------------------------------------------------------------------------------- /src/haskell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/haskell.png -------------------------------------------------------------------------------- /src/jquery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/jquery.png -------------------------------------------------------------------------------- /src/jqueryui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/jqueryui.png -------------------------------------------------------------------------------- /src/knockout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/knockout.png -------------------------------------------------------------------------------- /src/kotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/kotlin.png -------------------------------------------------------------------------------- /src/laravel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/laravel.png -------------------------------------------------------------------------------- /src/lodash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/lodash.png -------------------------------------------------------------------------------- /src/lodash~3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/lodash~3.png -------------------------------------------------------------------------------- /src/lodash~4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/lodash~4.png -------------------------------------------------------------------------------- /src/markdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/markdown.png -------------------------------------------------------------------------------- /src/maxcdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/maxcdn.png -------------------------------------------------------------------------------- /src/meteor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/meteor.png -------------------------------------------------------------------------------- /src/minitest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/minitest.png -------------------------------------------------------------------------------- /src/moment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/moment.png -------------------------------------------------------------------------------- /src/mongoose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/mongoose.png -------------------------------------------------------------------------------- /src/nokogiri.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/nokogiri.png -------------------------------------------------------------------------------- /src/padrino.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/padrino.png -------------------------------------------------------------------------------- /src/phalcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/phalcon.png -------------------------------------------------------------------------------- /src/phaser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/phaser.png -------------------------------------------------------------------------------- /src/phpunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/phpunit.png -------------------------------------------------------------------------------- /src/postgres.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/postgres.png -------------------------------------------------------------------------------- /src/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/python.png -------------------------------------------------------------------------------- /src/ruby~2.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/ruby~2.2.png -------------------------------------------------------------------------------- /src/ruby~2.3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/ruby~2.3.png -------------------------------------------------------------------------------- /src/socketio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/socketio.png -------------------------------------------------------------------------------- /src/sphinx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/sphinx.png -------------------------------------------------------------------------------- /src/tcl_tk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/tcl_tk.png -------------------------------------------------------------------------------- /src/vagrant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/vagrant.png -------------------------------------------------------------------------------- /src/webpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/webpack.png -------------------------------------------------------------------------------- /src/yii~1.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/yii~1.1.png -------------------------------------------------------------------------------- /src/yii~2.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/yii~2.0.png -------------------------------------------------------------------------------- /src/angularjs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angularjs.png -------------------------------------------------------------------------------- /src/apache_pig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/apache_pig.png -------------------------------------------------------------------------------- /src/bootstrap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/bootstrap.png -------------------------------------------------------------------------------- /src/dom_events.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/dom_events.png -------------------------------------------------------------------------------- /src/gcc~4_cpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gcc~4_cpp.png -------------------------------------------------------------------------------- /src/gcc~5_cpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gcc~5_cpp.png -------------------------------------------------------------------------------- /src/influxdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/influxdata.png -------------------------------------------------------------------------------- /src/javascript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/javascript.png -------------------------------------------------------------------------------- /src/marionette.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/marionette.png -------------------------------------------------------------------------------- /src/modernizr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/modernizr.png -------------------------------------------------------------------------------- /src/node~4_lts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/node~4_lts.png -------------------------------------------------------------------------------- /src/postgresql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/postgresql.png -------------------------------------------------------------------------------- /src/rails~4.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/rails~4.1.png -------------------------------------------------------------------------------- /src/rails~4.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/rails~4.2.png -------------------------------------------------------------------------------- /src/rails~5.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/rails~5.0.png -------------------------------------------------------------------------------- /src/requirejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/requirejs.png -------------------------------------------------------------------------------- /src/rethinkdb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/rethinkdb.png -------------------------------------------------------------------------------- /src/tensorflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/tensorflow.png -------------------------------------------------------------------------------- /src/typescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/typescript.png -------------------------------------------------------------------------------- /src/underscore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/underscore.png -------------------------------------------------------------------------------- /src/xslt_xpath.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/xslt_xpath.png -------------------------------------------------------------------------------- /src/angularjs~1.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angularjs~1.2.png -------------------------------------------------------------------------------- /src/angularjs~1.3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angularjs~1.3.png -------------------------------------------------------------------------------- /src/angularjs~1.4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angularjs~1.4.png -------------------------------------------------------------------------------- /src/angularjs~1.5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angularjs~1.5.png -------------------------------------------------------------------------------- /src/coffeescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/coffeescript.png -------------------------------------------------------------------------------- /src/gnu_fortran~4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gnu_fortran~4.png -------------------------------------------------------------------------------- /src/gnu_fortran~5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gnu_fortran~5.png -------------------------------------------------------------------------------- /src/gnu_fortran~6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/gnu_fortran~6.png -------------------------------------------------------------------------------- /src/jquerymobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/jquerymobile.png -------------------------------------------------------------------------------- /src/laravel~5.1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/laravel~5.1.png -------------------------------------------------------------------------------- /src/laravel~5.2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/laravel~5.2.png -------------------------------------------------------------------------------- /src/react_native.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/react_native.png -------------------------------------------------------------------------------- /src/sphinx_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/sphinx_simple.png -------------------------------------------------------------------------------- /src/symfony~2.7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/symfony~2.7.png -------------------------------------------------------------------------------- /src/symfony~2.8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/symfony~2.8.png -------------------------------------------------------------------------------- /src/symfony~3.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/symfony~3.0.png -------------------------------------------------------------------------------- /src/codeigniter~3.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/codeigniter~3.0.png -------------------------------------------------------------------------------- /src/support_tables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/support_tables.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | src/cache/* 2 | src/docs/* 3 | .DS_Store 4 | src/.DS_Store 5 | .idea 6 | docs.json 7 | .vscode 8 | -------------------------------------------------------------------------------- /src/nginx_lua_module.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/nginx_lua_module.png -------------------------------------------------------------------------------- /src/angular~4_typescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angular~4_typescript.png -------------------------------------------------------------------------------- /src/angular~2.0_typescript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/angular~2.0_typescript.png -------------------------------------------------------------------------------- /src/scripts/vendor/rodneyrehm/plist/.gitignore: -------------------------------------------------------------------------------- 1 | docs 2 | *tmp 3 | composer.lock 4 | vendor 5 | .foundation 6 | Makefile 7 | .DS_Store 8 | -------------------------------------------------------------------------------- /src/scripts/vendor/rodneyrehm/plist/tests/binary-data.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/scripts/vendor/rodneyrehm/plist/tests/binary-data.plist -------------------------------------------------------------------------------- /src/scripts/vendor/rodneyrehm/plist/examples/sample.binary.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yannickglt/alfred-devdocs/HEAD/src/scripts/vendor/rodneyrehm/plist/examples/sample.binary.plist -------------------------------------------------------------------------------- /src/scripts/vendor/composer/autoload_psr4.php: -------------------------------------------------------------------------------- 1 | array($vendorDir . '/rodneyrehm/plist/classes'), 10 | ); 11 | -------------------------------------------------------------------------------- /src/scripts/vendor/rodneyrehm/plist/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | /bin/sh /opt/local/share/phpDoc/phpdoc -ed /Users/rrehm/Projekte/plist/examples -d /Users/rrehm/Projekte/plist/classes -ti "CFPropertyList" -t /Users/rrehm/Projekte/plist/docs/ -ue on 3 | 4 | cd /Users/rrehm/Projekte/plist/ 5 | tar --exclude=".git|*.sh" -czf ../CFPropertyList.tgz . 6 | -------------------------------------------------------------------------------- /src/scripts/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yannickglt/alfred-devdocs", 3 | "description": "Alfred workflow for devdocs.io", 4 | "authors": [ 5 | { 6 | "name": "Julien Vidal", 7 | "email": "julien.vidal.jv@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "rodneyrehm/plist": "2" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/scripts/vendor/rodneyrehm/plist/tests/xml-data.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | age 6 | 28 7 | birth-date 8 | 1983-01-21T22:23:23Z 9 | names 10 | 11 | given-name 12 | John 13 | surname 14 | Dow 15 | 16 | pets 17 | 18 | Jonny 19 | Bello 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/scripts/vendor/rodneyrehm/plist/classes/CFPropertyList/PListException.php: -------------------------------------------------------------------------------- 1 | 6 | * @author Christian Kruse 7 | * @package plist 8 | * @version $Id$ 9 | */ 10 | namespace CFPropertyList; 11 | 12 | /** 13 | * Exception for errors with the PList format 14 | * @author Rodney Rehm 15 | * @author Christian Kruse 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 [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](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 | ![AngularJS documentation](http://content.screencast.com/users/yannickglt/folders/Snagit/media/7492bbba-99b7-4a75-9b97-dfba08437d24/2014-08-04_14-40-20.png) 33 | 34 | ## Completion 35 | 36 | ![Filter on functions](http://content.screencast.com/users/yannickglt/folders/Snagit/media/eb943219-5275-4cf8-a915-a97ea1772fa0/2014-08-04_14-43-13.png) 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 | ![Global search](http://content.screencast.com/users/yannickglt/folders/Snagit/media/c6d429e4-2499-4764-91e5-06dba18ff392/2014-08-04_14-46-31.png) 42 | 43 | ## Alfred preview 44 | Using the "shift" key on a function will display a preview (using quicklook) of the doc. 45 | ![Preview](http://content.screencast.com/users/yannickglt/folders/Snagit/media/a339c2aa-a75d-4316-a8fb-d0d75e932912/2014-08-04_14-50-44.png) 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 | ![image](https://cloud.githubusercontent.com/assets/1006426/25639687/14c63202-2f8d-11e7-8384-a75ba0b7059d.png) 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 --------------------------------------------------------------------------------