Repository: AKSW/OntoWiki
Branch: develop
Commit: 817dbdd1f144
Files: 557
Total size: 4.3 MB
Directory structure:
gitextract_421r03jp/
├── .gitignore
├── .htaccess
├── .travis.yml
├── CHANGELOG.md
├── Makefile
├── README.md
├── application/
│ ├── Bootstrap.php
│ ├── LICENSE.txt
│ ├── classes/
│ │ ├── OntoWiki/
│ │ │ ├── Component/
│ │ │ │ ├── Exception.php
│ │ │ │ └── Helper.php
│ │ │ ├── Controller/
│ │ │ │ ├── ActionHelper/
│ │ │ │ │ └── List.php
│ │ │ │ ├── Base.php
│ │ │ │ ├── Component.php
│ │ │ │ ├── Exception.php
│ │ │ │ └── Plugin/
│ │ │ │ ├── HttpAuth.php
│ │ │ │ ├── ListSetupHelper.php
│ │ │ │ └── SetupHelper.php
│ │ │ ├── Dispatcher.php
│ │ │ ├── Exception.php
│ │ │ ├── Extension/
│ │ │ │ └── Manager.php
│ │ │ ├── Http/
│ │ │ │ └── Exception.php
│ │ │ ├── Jobs/
│ │ │ │ └── Cron.php
│ │ │ ├── Menu/
│ │ │ │ └── Registry.php
│ │ │ ├── Menu.php
│ │ │ ├── Message.php
│ │ │ ├── Model/
│ │ │ │ ├── Exception.php
│ │ │ │ ├── Hierarchy.php
│ │ │ │ ├── Instances.php
│ │ │ │ ├── Resource.php
│ │ │ │ └── TitleHelper.php
│ │ │ ├── Model.php
│ │ │ ├── Module/
│ │ │ │ ├── Exception.php
│ │ │ │ └── Registry.php
│ │ │ ├── Module.php
│ │ │ ├── Navigation.php
│ │ │ ├── Pager.php
│ │ │ ├── Plugin.php
│ │ │ ├── Request.php
│ │ │ ├── Resource.php
│ │ │ ├── Test/
│ │ │ │ ├── ControllerTestCase.php
│ │ │ │ ├── ExtensionIntegrationTestBootstrap.php
│ │ │ │ ├── ExtensionUnitTestBootstrap.php
│ │ │ │ ├── IntegrationTestBootstrap.php
│ │ │ │ └── UnitTestBootstrap.php
│ │ │ ├── Toolbar.php
│ │ │ ├── Url.php
│ │ │ ├── Utils/
│ │ │ │ └── Exception.php
│ │ │ ├── Utils.php
│ │ │ ├── View/
│ │ │ │ └── Helper/
│ │ │ │ └── Curie.php
│ │ │ └── View.php
│ │ └── OntoWiki.php
│ ├── config/
│ │ ├── SysBase/
│ │ │ ├── dc
│ │ │ ├── dcterms
│ │ │ ├── foaf
│ │ │ ├── geo
│ │ │ ├── owl
│ │ │ ├── rdf
│ │ │ ├── rdfs
│ │ │ ├── rel
│ │ │ ├── sioc
│ │ │ ├── sioct
│ │ │ ├── skos
│ │ │ └── tags
│ │ ├── SysBase.rdf
│ │ ├── application.ini
│ │ ├── default.ini
│ │ └── default.n3
│ ├── controllers/
│ │ ├── ApplicationController.php
│ │ ├── DebugController.php
│ │ ├── ErrorController.php
│ │ ├── IndexController.php
│ │ ├── ModelController.php
│ │ ├── ModuleController.php
│ │ ├── ResourceController.php
│ │ └── ServiceController.php
│ ├── scripts/
│ │ ├── README-Vagrant.md
│ │ ├── clearCache.php
│ │ ├── extensions-ini2n3.php
│ │ ├── makeBackup.sh
│ │ ├── makeRelease.sh
│ │ ├── mod-auth-external/
│ │ │ └── ontowiki.php
│ │ ├── odbctest.php
│ │ ├── owadmin.php
│ │ ├── runExtensionTests.sh
│ │ ├── travis/
│ │ │ ├── README.md
│ │ │ ├── install-extensions.sh
│ │ │ ├── install-services.sh
│ │ │ └── virtuoso-sparql-permission.sql
│ │ └── vad/
│ │ ├── README.txt
│ │ ├── ow_vad_sticker_template.xml
│ │ ├── ow_vad_sticker_template.xml_not_working
│ │ ├── prepare.sh
│ │ └── vad.ini
│ ├── shell.worker.client.php
│ ├── shell.worker.php
│ ├── tests/
│ │ ├── Bootstrap.php
│ │ ├── BootstrapExtensions.php
│ │ ├── CodeSniffer/
│ │ │ └── Standards/
│ │ │ └── Ontowiki/
│ │ │ ├── Sniffs/
│ │ │ │ ├── Classes/
│ │ │ │ │ └── ClassFilePathSniff.php
│ │ │ │ ├── Commenting/
│ │ │ │ │ └── FileCommentSniff.php
│ │ │ │ ├── Functions/
│ │ │ │ │ ├── ForbiddenFunctionsSniff.php
│ │ │ │ │ └── FunctionCallArgumentSpacingSniff.php
│ │ │ │ └── PHP/
│ │ │ │ └── GetRequestDataSniff.php
│ │ │ └── ruleset.xml
│ │ ├── config.ini.dist
│ │ ├── config.ini.dist.travis
│ │ ├── integration/
│ │ │ ├── OntoWiki/
│ │ │ │ ├── Extension/
│ │ │ │ │ ├── ManagerIntegrationTest.php
│ │ │ │ │ └── _files/
│ │ │ │ │ ├── test1/
│ │ │ │ │ │ ├── MoreModule.php
│ │ │ │ │ │ ├── Test1Controller.php
│ │ │ │ │ │ ├── TestModule.php
│ │ │ │ │ │ └── doap.n3
│ │ │ │ │ ├── test2/
│ │ │ │ │ │ ├── Test2Plugin.php
│ │ │ │ │ │ ├── Test2Wrapper.php
│ │ │ │ │ │ └── doap.n3
│ │ │ │ │ └── test2.ini
│ │ │ │ └── Model/
│ │ │ │ ├── InstancesIntegrationTest.php
│ │ │ │ └── TitleHelperIntegrationTest.php
│ │ │ ├── controller/
│ │ │ │ ├── ModelControllerTest.php
│ │ │ │ └── ServiceControllerTest.php
│ │ │ └── phpunit.xml.dist
│ │ └── unit/
│ │ ├── OntoWiki/
│ │ │ ├── Extension/
│ │ │ │ ├── ManagerTest.php
│ │ │ │ └── _files/
│ │ │ │ └── test-doap.n3
│ │ │ ├── MenuTest.php
│ │ │ ├── MessageTest.php
│ │ │ ├── Model/
│ │ │ │ └── InstancesTest.php
│ │ │ ├── Module/
│ │ │ │ └── RegistryTest.php
│ │ │ ├── NavigationTest.php
│ │ │ └── UtilsTest.php
│ │ ├── OntoWikiTest.php
│ │ ├── controller/
│ │ │ ├── IndexControllerTest.php
│ │ │ ├── ResourceControllerTest.php
│ │ │ └── _files/
│ │ │ └── aksw.rss
│ │ └── phpunit.xml.dist
│ └── views/
│ └── templates/
│ ├── application/
│ │ ├── about.phtml
│ │ ├── openid.phtml
│ │ ├── register.phtml
│ │ ├── search.phtml
│ │ ├── userdetails.phtml
│ │ └── webid.phtml
│ ├── error/
│ │ ├── 404.phtml
│ │ ├── 500.phtml
│ │ └── error.phtml
│ ├── index/
│ │ ├── index.phtml
│ │ ├── news.phtml
│ │ └── newsshort.phtml
│ ├── layouts/
│ │ └── layout.phtml
│ ├── model/
│ │ ├── config.phtml
│ │ ├── create.phtml
│ │ └── info.phtml
│ ├── partials/
│ │ ├── contextmenu.phtml
│ │ ├── hierarchy_list.phtml
│ │ ├── list.phtml
│ │ ├── list_std_element.phtml
│ │ ├── list_std_main.phtml
│ │ ├── menu.phtml
│ │ ├── message.phtml
│ │ ├── meta.phtml
│ │ ├── module.phtml
│ │ ├── navigation.phtml
│ │ ├── resultset.phtml
│ │ ├── statusbar.phtml
│ │ ├── table.phtml
│ │ ├── toolbar.phtml
│ │ └── window.phtml
│ └── resource/
│ ├── instances.phtml
│ └── properties.phtml
├── build/
│ └── phpcs.xml
├── build.xml
├── composer.json
├── config.ini.dist
├── debian/
│ ├── Makefile/
│ │ └── Makefile
│ ├── changelog
│ ├── compat
│ ├── conf/
│ │ ├── apache2/
│ │ │ └── apache.conf
│ │ ├── gnome/
│ │ │ └── ontowiki.desktop
│ │ ├── mysql/
│ │ │ └── config.ini
│ │ └── virtuoso/
│ │ └── config.ini
│ ├── control
│ ├── copyright
│ ├── ontowiki-common.dirs
│ ├── ontowiki-common.install
│ ├── ontowiki-common.links
│ ├── ontowiki-common.postinst
│ ├── ontowiki-mysql.install
│ ├── ontowiki-mysql.links
│ ├── ontowiki-mysql.postinst
│ ├── ontowiki-mysql.prerm
│ ├── ontowiki-virtuoso.install
│ ├── ontowiki-virtuoso.links
│ ├── ontowiki-virtuoso.postinst
│ ├── rules
│ ├── source/
│ │ └── format
│ └── sql/
│ └── install/
│ ├── mysql
│ └── virtuoso
├── extensions/
│ ├── account/
│ │ ├── AccountController.php
│ │ ├── LoginModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── languages/
│ │ │ ├── account-de.csv
│ │ │ └── account-en.csv
│ │ └── templates/
│ │ ├── account/
│ │ │ └── recover.phtml
│ │ ├── local.phtml
│ │ ├── mail/
│ │ │ ├── html/
│ │ │ │ └── default.phtml
│ │ │ └── text/
│ │ │ └── default.txt
│ │ ├── openid.phtml
│ │ └── webid.phtml
│ ├── application/
│ │ ├── ApplicationModule.php
│ │ ├── application.phtml
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── auth/
│ │ ├── AuthController.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── languages/
│ │ │ ├── auth-de.csv
│ │ │ └── auth-en.csv
│ │ └── templates/
│ │ └── auth/
│ │ ├── cert1.phtml
│ │ └── cert2.phtml
│ ├── autologin/
│ │ ├── AutologinPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── basicimporter/
│ │ ├── BasicimporterController.php
│ │ ├── BasicimporterPlugin.php
│ │ ├── SelectorModule.js
│ │ ├── SelectorModule.php
│ │ ├── doap.n3
│ │ ├── languages/
│ │ │ ├── basicimporter-de.csv
│ │ │ └── basicimporter-en.csv
│ │ └── templates/
│ │ └── basicimporter/
│ │ ├── category.phtml
│ │ ├── prefix.phtml
│ │ ├── rdfpaster.phtml
│ │ ├── rdfupload.phtml
│ │ ├── rdfwebimport.phtml
│ │ └── search.phtml
│ ├── bookmarklet/
│ │ ├── BookmarkletModule.php
│ │ ├── bookmarklet.phtml
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── ckan/
│ │ ├── CkanController.php
│ │ ├── CkanHelper.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── templates/
│ │ └── ckan/
│ │ └── browser.phtml
│ ├── community/
│ │ ├── CommentModule.php
│ │ ├── CommunityController.php
│ │ ├── CommunityHelper.php
│ │ ├── LastchangesModule.php
│ │ ├── RatingModule.php
│ │ ├── default.ini
│ │ ├── default.n3
│ │ ├── doap.n3
│ │ ├── insert.sparql
│ │ ├── jquery.MetaData.js
│ │ ├── jquery.rating.css
│ │ ├── jquery.rating.js
│ │ ├── jquery.rating.pack.js
│ │ ├── languages/
│ │ │ ├── community-de.csv
│ │ │ └── community-en.csv
│ │ ├── rating.js
│ │ ├── styles/
│ │ │ └── community.css
│ │ └── templates/
│ │ ├── comment.phtml
│ │ ├── community/
│ │ │ └── list.phtml
│ │ ├── lastchanges.phtml
│ │ ├── lastcomments.phtml
│ │ ├── partials/
│ │ │ ├── list_community_item.phtml
│ │ │ └── list_community_main.phtml
│ │ └── rating.phtml
│ ├── cors/
│ │ ├── CorsPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── datagathering/
│ │ ├── DatagatheringController.php
│ │ ├── DatagatheringHelper.php
│ │ ├── DatagatheringPlugin.php
│ │ ├── SyncSchema.rdf
│ │ ├── css/
│ │ │ └── jquery.autocomplete.css
│ │ ├── datagathering.js
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── languages/
│ │ │ ├── datagathering-de.csv
│ │ │ └── datagathering-en.csv
│ │ ├── scripts/
│ │ │ └── jquery.autocomplete.js
│ │ ├── templates/
│ │ │ └── datagathering/
│ │ │ └── config.phtml
│ │ └── tests/
│ │ └── DatagatheringControllerTest.php
│ ├── defaultmodel/
│ │ ├── DefaultmodelPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── exconf/
│ │ ├── Archive.php
│ │ ├── ExconfController.php
│ │ ├── ExconfHelper.php
│ │ ├── OutlineModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── pclzip.lib.php
│ │ ├── resources/
│ │ │ ├── Examples.rdf
│ │ │ ├── PluginRepository.rdf
│ │ │ ├── exconf.css
│ │ │ ├── exconf.js
│ │ │ ├── jquery.togglebutton.js
│ │ │ ├── outline.js
│ │ │ └── togglebutton.css
│ │ └── templates/
│ │ ├── exconf/
│ │ │ ├── archiveuploadform.phtml
│ │ │ ├── conf.phtml
│ │ │ ├── explorerepo.phtml
│ │ │ ├── installarchiveremote.phtml
│ │ │ ├── installarchiveupload.phtml
│ │ │ └── list.phtml
│ │ └── partials/
│ │ └── list_extensions_main.phtml
│ ├── filter/
│ │ ├── CustomfilterModule.php
│ │ ├── FilterController.php
│ │ ├── FilterModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── resources/
│ │ │ ├── FilterAPI.js
│ │ │ ├── filter.css
│ │ │ ├── filter.js
│ │ │ ├── jquery.dump.js
│ │ │ ├── jquery.treeview.css
│ │ │ └── jquery.treeview.js
│ │ └── templates/
│ │ └── filter/
│ │ ├── complexfilter.phtml
│ │ ├── filter.phtml
│ │ └── getpossiblevalues.phtml
│ ├── googletracking/
│ │ ├── GoogletrackingPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── hideproperties/
│ │ ├── HidepropertiesPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── history/
│ │ ├── HistoryController.php
│ │ ├── HistoryHelper.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── languages/
│ │ │ ├── history-de.csv
│ │ │ └── history-en.csv
│ │ └── templates/
│ │ └── history/
│ │ ├── details.phtml
│ │ ├── list.phtml
│ │ └── rollback.phtml
│ ├── imagelink/
│ │ ├── ImagelinkPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── imprint/
│ │ ├── ImprintModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── imprint.phtml
│ ├── jsonrpc/
│ │ ├── EvolutionJsonrpcAdapter.php
│ │ ├── JsonrpcController.php
│ │ ├── MetaJsonrpcAdapter.php
│ │ ├── ModelJsonrpcAdapter.php
│ │ ├── ResourceJsonrpcAdapter.php
│ │ ├── StoreJsonrpcAdapter.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── languages/
│ │ └── community-en.csv
│ ├── linkeddataserver/
│ │ ├── LinkeddataPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── listmodules/
│ │ ├── ShowpropertiesModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── showproperties.js
│ │ └── showproperties.phtml
│ ├── literaltypes/
│ │ ├── LiteraltypesPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── mail/
│ │ ├── MailPlugin.php
│ │ ├── doap.n3
│ │ └── jobs/
│ │ └── Mail.php
│ ├── mailtolink/
│ │ ├── MailtolinkPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── manchester/
│ │ ├── ManchesterController.php
│ │ ├── ManchesterModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── templates/
│ │ └── modules/
│ │ └── manchester.phtml
│ ├── markdown/
│ │ ├── MarkdownPlugin.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── parser/
│ │ ├── License.text
│ │ ├── PHP Markdown Readme.text
│ │ └── markdown.php
│ ├── modellist/
│ │ ├── ModellistModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── modellist.js
│ │ └── modellist.phtml
│ ├── navigation/
│ │ ├── NavigationController.php
│ │ ├── NavigationHelper.php
│ │ ├── NavigationModule.php
│ │ ├── doap.n3
│ │ ├── languages/
│ │ │ ├── navigation-de.csv
│ │ │ └── navigation-en.csv
│ │ ├── navigation.css
│ │ ├── navigation.js
│ │ ├── navigation.phtml
│ │ └── templates/
│ │ └── navigation/
│ │ ├── explore.phtml
│ │ └── loadstate.phtml
│ ├── pingback/
│ │ ├── PingbackController.php
│ │ ├── PingbackPlugin.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── templates/
│ │ └── pingback/
│ │ └── ping.phtml
│ ├── queries/
│ │ ├── QueriesController.php
│ │ ├── QueriesHelper.php
│ │ ├── SavequeryModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── log/
│ │ │ ├── getAutocompletionQuery.log
│ │ │ ├── getSPARQLQuery.log
│ │ │ └── updateTable.log
│ │ ├── resources/
│ │ │ ├── codemirror/
│ │ │ │ ├── CONTRIBUTING.md
│ │ │ │ ├── LICENSE
│ │ │ │ ├── README.md
│ │ │ │ ├── addon/
│ │ │ │ │ ├── dialog/
│ │ │ │ │ │ ├── dialog.css
│ │ │ │ │ │ └── dialog.js
│ │ │ │ │ ├── edit/
│ │ │ │ │ │ ├── closetag.js
│ │ │ │ │ │ ├── continuecomment.js
│ │ │ │ │ │ ├── continuelist.js
│ │ │ │ │ │ └── matchbrackets.js
│ │ │ │ │ ├── fold/
│ │ │ │ │ │ ├── collapserange.js
│ │ │ │ │ │ └── foldcode.js
│ │ │ │ │ ├── format/
│ │ │ │ │ │ └── formatting.js
│ │ │ │ │ ├── hint/
│ │ │ │ │ │ ├── javascript-hint.js
│ │ │ │ │ │ ├── pig-hint.js
│ │ │ │ │ │ ├── python-hint.js
│ │ │ │ │ │ ├── simple-hint.css
│ │ │ │ │ │ ├── simple-hint.js
│ │ │ │ │ │ └── xml-hint.js
│ │ │ │ │ ├── mode/
│ │ │ │ │ │ ├── loadmode.js
│ │ │ │ │ │ ├── multiplex.js
│ │ │ │ │ │ └── overlay.js
│ │ │ │ │ ├── runmode/
│ │ │ │ │ │ ├── colorize.js
│ │ │ │ │ │ ├── runmode-standalone.js
│ │ │ │ │ │ ├── runmode.js
│ │ │ │ │ │ └── runmode.node.js
│ │ │ │ │ └── search/
│ │ │ │ │ ├── match-highlighter.js
│ │ │ │ │ ├── search.js
│ │ │ │ │ └── searchcursor.js
│ │ │ │ ├── keymap/
│ │ │ │ │ ├── emacs.js
│ │ │ │ │ └── vim.js
│ │ │ │ ├── lib/
│ │ │ │ │ ├── codemirror.css
│ │ │ │ │ └── codemirror.js
│ │ │ │ ├── mode/
│ │ │ │ │ ├── meta.js
│ │ │ │ │ ├── ntriples/
│ │ │ │ │ │ └── ntriples.js
│ │ │ │ │ ├── sparql/
│ │ │ │ │ │ └── sparql.js
│ │ │ │ │ └── xml/
│ │ │ │ │ └── xml.js
│ │ │ │ └── theme/
│ │ │ │ ├── ambiance-mobile.css
│ │ │ │ ├── ambiance.css
│ │ │ │ ├── blackboard.css
│ │ │ │ ├── cobalt.css
│ │ │ │ ├── eclipse.css
│ │ │ │ ├── elegant.css
│ │ │ │ ├── erlang-dark.css
│ │ │ │ ├── lesser-dark.css
│ │ │ │ ├── monokai.css
│ │ │ │ ├── neat.css
│ │ │ │ ├── night.css
│ │ │ │ ├── rubyblue.css
│ │ │ │ ├── solarized.css
│ │ │ │ ├── twilight.css
│ │ │ │ ├── vibrant-ink.css
│ │ │ │ └── xq-dark.css
│ │ │ ├── querieseditor.css
│ │ │ └── savepartial.js
│ │ └── templates/
│ │ ├── partials/
│ │ │ ├── list_queries_element.phtml
│ │ │ └── list_queries_main.phtml
│ │ ├── queries/
│ │ │ ├── editor.phtml
│ │ │ ├── listquery.phtml
│ │ │ ├── manage.phtml
│ │ │ └── savequery.phtml
│ │ ├── queryeditorfromsetter.phtml
│ │ ├── savequery.phtml
│ │ └── sparqloptions.phtml
│ ├── resourcecreationuri/
│ │ ├── ResourcecreationuriPlugin.php
│ │ ├── classes/
│ │ │ └── ResourceUriGenerator.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── resourcemodules/
│ │ ├── LinkinghereModule.php
│ │ ├── SimilarinstancesModule.php
│ │ ├── UsageModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── linkinghere.phtml
│ │ ├── similarinstances.phtml
│ │ └── usage.phtml
│ ├── savedqueries/
│ │ ├── SavedqueriesController.php
│ │ ├── SavedqueriesModule.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── savedqueries.phtml
│ │ └── templates/
│ │ └── savedqueries/
│ │ └── init.phtml
│ ├── selectlanguage/
│ │ ├── SelectlanguagePlugin.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ └── languages/
│ │ └── selectlanguage-de.csv
│ ├── semanticsitemap/
│ │ ├── SemanticsitemapController.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── semanticsitemap.php
│ │ └── templates/
│ │ └── semanticsitemap/
│ │ └── sitemap.phtml
│ ├── sendmail/
│ │ ├── SendmailPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── sindice/
│ │ ├── SindicePlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── sortproperties/
│ │ ├── SortpropertiesPlugin.php
│ │ ├── default.ini
│ │ └── doap.n3
│ ├── source/
│ │ ├── SourceController.php
│ │ ├── SourceHelper.php
│ │ ├── default.ini
│ │ ├── doap.n3
│ │ ├── templates/
│ │ │ └── source/
│ │ │ └── edit.phtml
│ │ └── tests/
│ │ └── SourceControllerTest.php
│ ├── themes/
│ │ ├── .htaccess
│ │ ├── darkorange/
│ │ │ ├── install.txt
│ │ │ └── styles/
│ │ │ └── default.css
│ │ └── silverblue/
│ │ ├── sandbox/
│ │ │ ├── detailview.html
│ │ │ ├── filter.html
│ │ │ ├── forms.html
│ │ │ ├── listview.html
│ │ │ ├── tables.html
│ │ │ ├── uitest.html
│ │ │ └── uitestow.html
│ │ ├── scripts/
│ │ │ ├── jquery.ontowiki.js
│ │ │ ├── libraries/
│ │ │ │ ├── jquery-1.9.1.js
│ │ │ │ ├── jquery-migrate-1.3.0.js
│ │ │ │ ├── jquery-ui-1.8.22.js
│ │ │ │ ├── jquery.clickmenu.js
│ │ │ │ ├── jquery.dimensions.js
│ │ │ │ ├── jquery.interface.js
│ │ │ │ ├── jquery.json.js
│ │ │ │ ├── jquery.livequery.js
│ │ │ │ ├── jquery.rdfquery.rdfa-1.0.js
│ │ │ │ ├── jquery.simplemodal.js
│ │ │ │ └── jquery.tablesorter.js
│ │ │ ├── main.js
│ │ │ ├── serialize-php.js
│ │ │ └── support.js
│ │ └── styles/
│ │ ├── clickmenu.css
│ │ ├── default.css
│ │ ├── default.dev.css
│ │ ├── deprecated.dev.css
│ │ ├── jquery-ui.css
│ │ ├── old.css
│ │ └── patches/
│ │ ├── ie6.clickmenu.css
│ │ ├── ie6.css
│ │ └── ie7.css
│ ├── translations/
│ │ ├── de/
│ │ │ └── core.csv
│ │ ├── en/
│ │ │ └── core.csv
│ │ ├── fr/
│ │ │ └── core.csv
│ │ ├── ru/
│ │ │ └── core.csv
│ │ └── zh/
│ │ └── core.csv
│ └── weblink/
│ ├── WeblinkPlugin.php
│ └── doap.n3
├── index.php
├── phpcs.xml
├── phpunit.xml
└── web.config
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# OntoWiki configs
/config.ini
/local.ini
# OntoWiki muck
*.log
application/tests/cache
/cache
/uploads
/libraries
/logs
# Extensions
/extensions/*.ini
/extensions/*
!/extensions/account
!/extensions/application
!/extensions/auth
!/extensions/autologin
!/extensions/basicimporter
!/extensions/bookmarklet
!/extensions/ckan
!/extensions/community
!/extensions/cors
!/extensions/datagathering
!/extensions/defaultmodel
!/extensions/exconf
!/extensions/filter
!/extensions/googletracking
!/extensions/hideproperties
!/extensions/history
!/extensions/imagelink
!/extensions/imprint
!/extensions/jsonrpc
!/extensions/linkeddataserver
!/extensions/listmodules
!/extensions/literaltypes
!/extensions/mail
!/extensions/mailtolink
!/extensions/manchester
!/extensions/markdown
!/extensions/modellist
!/extensions/navigation
!/extensions/pingback
!/extensions/queries
!/extensions/resourcecreationuri
!/extensions/resourcemodules
!/extensions/savedqueries
!/extensions/selectlanguage
!/extensions/semanticsitemap
!/extensions/sendmail
!/extensions/sindice
!/extensions/sortproperties
!/extensions/source
!/extensions/themes
!/extensions/translations
!/extensions/weblink
# aksw specific mud
/BlogPost
/extensions/dssn/libraries/lib-dssn-php
# ide and editor dirt
.settings
.project
.idea
.buildpath
.DS_Store
nbproject
*~
*.swp
cache.properties
# test stuff
application/tests/config.ini
# build stuff
build/
!build/phpcs.xml
!build/phpcmd.xml
# composer stuff
/vendor
composer.phar
# for now we ignore the composer.lock, but we should commit it some dome day, especially for releases
# devenv stuff
/devenv
================================================
FILE: .htaccess
================================================
# OntoWiki .htaccess file
# WARNING: If you do not use the htaccess at all or your htaccess is
# ignored, then your config.ini can be loaded over the web !!!
Deny from all
# OntoWiki does not requires Apache's rewrite engine to work. However,
# if you would like to have nice (Linked Data) URIs you must enable URL
# rewriting by enabling mod_rewrite in your apache config.
RewriteEngine On
# This gives ontowiki an easy hint that rewrite is enabled
SetEnv ONTOWIKI_APACHE_MOD_REWRITE_ENABLED 1
# for deployment purposes, we want to redirect to a maintenance page iff it exists
# works only if document root is ontowiki folder
#RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f
#RewriteCond %{REQUEST_FILENAME} !/maintenance.html
#RewriteRule ^.*$ /maintenance.html [R=503,L]
#ErrorDocument 503 /maintenance.html
# favicon files are located under /application
RewriteRule ^favicon\.(.*)$ application/favicon.$1
# do not rewrite requests on /robots.txt or /maintenance.html
RewriteCond %{REQUEST_URI} !/(robots.txt|maintenance.html)$
# do not rewrite requests on resource under public in extensions
RewriteCond %{REQUEST_URI} !/extensions/.*/public/.*$
# do not rewrite requests on /favicon.ico and /favicon.png
RewriteCond %{REQUEST_URI} !/favicon\.(ico|png)$
# do not rewrite requests on files with the whitelisted extensions under extensions (if file exists)
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} !/extensions/.*/.*\.(js|css|gif|ico|png|jpg|svg)$
# do not rewrite requests on files with the whitelisted extensions under libraries/RDFauthor (if file exists)
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_URI} !/libraries/RDFauthor/.*/.*\.(js|css|gif|ico|png|jpg|svg)$
RewriteRule ^.*$ index.php
# Set RewriteBase if your OntoWiki virtual host is managed with VirtualDocumentRoot.
#RewriteBase /
# Set RewriteBase only if your OntoWiki folder is not located in your web server's root dir.
#RewriteBase /ontowiki
# if you allow short open tags, xml templates will crash
# please refer https://github.com/AKSW/OntoWiki/wiki/php.ini-recommendations
# for recommended PHP settings
# maybe php_flag is not allowed in your environment,
# but if you allow short open tags, xml templates will crash
#php_flag short_open_tag 0
### Additional Auth with external OntoWiki auth-script
### (more infos at http://code.google.com/p/mod-auth-external/)
#AuthType Basic
#AuthName OntoWiki
#AuthBasicProvider external
#AuthExternal ontowiki
#Require valid-user
### NOTE: This is needed to be included in /etc/apache2/mods-enabled/authnz_external.load or .conf
#DefineExternalAuth ontowiki pipe /path/to/ontowiki/application/scripts/mod-auth-external/ontowiki.php
================================================
FILE: .travis.yml
================================================
language: php
php:
- 5.4
- 5.6.29
- 7.0
- 7.1
env:
- VIRTUOSO=6.1.7
- VIRTUOSO=7.0.0
- VIRTUOSO=7.2.0
matrix:
fast_finish: true
include:
- php: 5.4
env: VIRTUOSO=6.1.6
- php: 5.4
env: VIRTUOSO=7.2.4.2
allow_failures:
- php: 7.0
- php: 7.1
- env: VIRTUOSO=7.2.4.2
cache:
directories:
- $HOME/.composer/cache
- virtuoso-opensource
sudo: true
services:
- mysql
before_install:
- sudo apt-get -qq update
- bash ./application/scripts/travis/install-extensions.sh
- bash ./application/scripts/travis/install-services.sh
- sudo apt-get install -y raptor2-utils
- phpenv config-rm xdebug.ini
- mysql -e 'CREATE DATABASE ontowiki_TEST;'
install:
- travis_retry composer install --no-interaction
before_script:
- cp ./application/tests/config.ini.dist.travis ./application/tests/config.ini
- make directories
script:
- vendor/bin/phpunit --testsuite "OntoWiki Unit Tests"
- EF_STORE_ADAPTER=zenddb vendor/bin/phpunit --testsuite "OntoWiki ZendDB Integration Tests"
- EF_STORE_ADAPTER=virtuoso vendor/bin/phpunit --testsuite "OntoWiki Virtuoso Integration Tests"
- vendor/bin/phpunit --testsuite "OntoWiki Extensions Tests"
================================================
FILE: CHANGELOG.md
================================================
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/) as of version 1.0.0.
## [1.0.0] - 2016-10-04
### Added
- Add a help text for the filter module
- Add option to (not) display default type column
- Add first draft (incomplete) to provide french
- SPARQL: add option to export result to CSV
- Add hide type when using add instance
- Add json-support for registrationAction
- Add prependTitleProperty again, remove unused methods and keep a single instance of erfurt
- Add showHiddenElements to naviagtion config
- Add hugarian to language selection
- Add initial ResourceJsonrpcAdapter
- Add getTitle method to ModelJsonrpcAdapter
- Add RDF/JSON (Alternate, Talis) content type
- Add support for attributes in toolbar buttons
- Add support for docker based devenv
- Add controller test for resource export action
- Add an onRegisterUser Event
- Add an onRegisterUserFailed Event
- Add test makefile for new composer download
### Changed
- Update RDFauthor
- Use onResolveDomainAliasInput on URL detection
- TitleHelper improvements: Chunk/Bulk Querying
- Changing the workflow of the TitleHelper using the ResourcePool
- Update getValues functionality using the ResourcePool - Scalability Improvement
- Changing getAllProperties functionality to work with the MemoryModel and ResourcePool
- Changing debug workflow with blanknodes on gettitles + cleanup
- Changing debug workflow on addResource
- Re-enabling inverse show properties in table view but on a scaleable way
- Change sameTerm Filter into Equals constraint in NavigationController
- Make new TitleHelper aware of languages
- Add getResources() call and unify testShownPropertiesAddTitles
- Set zend version to latest 1.x. Fix #306.
- Move responsibility for contentType and fileExtension to Erfurt
- Improve Exception output
- Update jQuery to 1.9.1 and add jQuery migrate
- Using composer for dependencies
- Update jquery-ui to 1.8.22. Fix #337
- Refactor usage of exit to using return
- Clean up default.ini/config.ini.dist, disable caches per default
- Remove trim() to give more meaningfull output
- Improve FileCommentSniff to also accept older years and to ignore sub repos
- Increse minimal PHP version to 5.4.0
- Change sort option to SORT_NUMERIC
- Modify help menu building process
- Deactivate ckan, mail and pingback extension
- Add data route to default config
- Update Linked Data plugin to use data route
- Enhance environment for controller unit tests
- Replace sameterm with equals in navbox
- Use IN where possible
- Optimize offset/limit usage & refactor js code a bit
- Make codesniffer now ignores the FileCommentSniff and make codesniffer_year includes the Sniff
- Disable front-end cache in config.ini.dist
- Change the Documentation link from Github to the new Documentation
### Fixed
- Fix type handling in rdfauthor popover controller
- Fix #278 Add Property not working properly
- Complete license and copyright information in doc blocks
- Additional fixes while firing onRegisterUser and onRegisterUserFailed event
- added workaround to handle statements with empty object URIs, which are sometimes provided by RDFauthor editor (seems to be related to line 467 in extensions/themes/silverblue/scripts/support.js)
- Only Uris should be used as links in a List. BugFix
- Prevent Bugs with wrong initalized class attributes
- Fix try to get property of non-object, when deleting model
- Fix pingback takes for ever
- Fix #286. Also consider colon in OntoWiki_Utils::compactUri method.
- Fix #258. Forward Erfurt.
- Fix community tab
- Fix selectlanguage config for russian
- Fix comments if creator not set.
- Fix getting branch name (wasn't language independent)
- Fix #145. Fix special chars in Linked Data request URIs.
- Fix testing for extensions
- Fix handling of protocols forwarded by proxy. Fix #313.
- Fix typo in Bootstrap comment
- Fix 319. Expose navigationAddElement in navigation.js
- Fix setting select clause instead of prologue part and forward Erfurt
- Fall back if no feed is specified
- Fix #347. Remove require_once because we are using autoloader now
- Fix skipped test
- Fix integration tests to fit new result format
- #332: Fix "Shift + Alt" key capture issue
- Fix content-type for resource exports
- Fix support for JSON content types in Linked Data plugin
- Fix indentation of mappings array
### Removed
- Removing subjects from inverse relations memory model
- Remove OntoWiki_Controller_Service. Fix #242.
- Remove useless add-method from ResourceJsonrpcAdapter
- Remove Vagrant development environment
- Remove test target in makefile
## [0.9.11] - 2014-01-31
- Improve model selection in linkeddataserver extension
- Extend cache clear script by support for query and translation cache
- Fix #60: Add script to clear cache via shell
- fix #201 - removed css classes for modal and set z-index of applicationbar to 999
- Fix 271. Fix Output Format of queries editor
- fix #201 - fixed z-index for modal-wrapper-propertyselector
- Merge pull request #268 from hknochi/feature/fix-extension-enabler
- Merge pull request #269 from hknochi/feature/fix-pagination
- fix issue #167 - invalidate extensionCache to distribute requested changes
- fix issue #261 - added limit-parameter to url
- improve cron job
- Add list-events target to Makefile
- remove log in about screen
- avoid broken feed URLs on version / names with spaces
- use configure name instead of hardcoded one
- fixed issue #201 - added css rules for modal-wrapper
- fixed issue #201 - added css rules for simplemodal-container and -overlay
- Fix build to ignore worker shell scripts
- Reorganize shell scripts to avoid build failure
- Cleanup mail extension job class by removing obsolete members
- Added console client and an example extension for testing Erfurts worker
- Add support for Erfurts background jobs
- add min-height to in resource view
- Add hidden save and cancle buttons in listmode
- Reorganize some code in support.js
- Fix editProperty to work in extended mode (+)
- Allow configuration of session cookie parameters, such as session lifetime
- Fix #259. Write alle defined prefixes to RDFa output.
- Fix warning, when site redirect takes place. Fix #260.
- fix wrong server class includes (closes #256)
- initial version of SelectorModule
- Fix model creation if no title is specified
- move inner window modules outside of master form
- Add “View as Resource” entry to model menu. Fix #152
- fix wrong encoded query parameter
- add even/odd classes for row and noodds parameter
- use new querylink feature of table partial
- remake table partial, add query link enhancement
- Fix #152. Move menu creation to Menu_Registry.
- add xdebug link
- Remove unused action service/entities
## [0.9.10] - 2013-07-11
- new model creation / add data procedure
- fixes in query editor
- performance issues in title helper
- unify CommentModule and LastcommentsModule, increase limit and set ordering
- +100 other commits
- depends on Erfurt 1.6
- depends on RDFauthor 0.9.6
## [0.9.8] - 2013-02-01
- fix cors header
- add doap:wiki to the weblink list (2 weeks ago by Sebastian Tramp)
- add head action to return the request header for given uri
- fix extensions setting page (toggleswitch) #179
- Fixing Sort functionality of the Navigation Box extension re-enabling the Sort Menue
- prevent open paranthesis bug while using the limit buttons (100 / all)
- Fix #172 - rewrite rules in .htaccess
- use getReadableGraphsUsingResource method on Store
- cleanup togglebutton changes
- fix toggle button for new jquery version (#167)
- depends on Erfurt 1.5
- depends on RDFauthor 0.9.5
## [0.9.7] - 2012-11-27
- GUI niceups
- lots of fixes
- https://github.com/AKSW/OntoWiki/issues?milestone=1&page=1&state=closed
- RDFauthor is now a separate package
- Add support for additonal vhosts
- increment RDFauthor dependency
- allow usage of virtuosos bd.ini if present
- add gnome desktop file
## 0.9.6-21 - 2012-03-03
- fix RDFauthor integration
- forward RDFauthor to b780680
- forward OntoWiki to 04b33fd
[1.0.0]: https://github.com/AKSW/OntoWiki/compare/v0.9.11...v1.0.0
[0.9.11]: https://github.com/AKSW/OntoWiki/compare/v0.9.10...v0.9.11
[0.9.10]: https://github.com/AKSW/OntoWiki/compare/v0.9.8...v0.9.10
[0.9.8]: https://github.com/AKSW/OntoWiki/compare/v0.9.7...v0.9.8
[0.9.7]: https://github.com/AKSW/OntoWiki/compare/v0.9.6-21...v0.9.7
================================================
FILE: Makefile
================================================
PHPUNIT = ./vendor/bin/phpunit
PHPCS = ./vendor/bin/phpcs
PHPCBF = ./vendor/bin/phpcbf
# Get calid composer executable
COMPOSER = $(shell which composer)
ifeq ($(findstring composer, $(COMPOSER)), )
COMPOSER = $(shell which composer.phar)
ifeq ($(findstring composer.phar, $(COMPOSER)), )
ifneq ($(wildcard composer.phar), )
COMPOSER = php composer.phar
else
COMPOSER =
endif
endif
endif
default:
@echo "Typical targets your could want to reach:"
@echo ""
@echo "--> make deploy ............... Install OntoWiki <-- in doubt, use this"
@echo " make install .............. deploy and install are equivalent"
@echo ""
@echo " make help ................. Show more (developer related) make targets"
@echo ""
@echo " make help-cs .............. Show help for code sniffing targets"
@echo ""
@echo " make help-test ............ Show help for test related targets"
help:
@echo "Please use: (e.g. make deploy)"
@echo " deploy ..................... Runs everything which is needed for a deployment"
@echo " install .................... Equivalent to deploy"
@echo " help ....................... This help screen"
@echo " help-cs .................... Show help for code sniffing targets"
@echo " help-test .................. Show help for test related targets"
@echo " -------------------------------------------------------------------"
@echo " directories ................ Create cache/log dir and chmod environment"
@echo " clean ...................... Deletes all log and cache files"
@echo " odbctest ................... Executes some tests to check the Virtuoso connection"
help-cs:
@echo "Please use: (e.g. make codesniffer)"
@echo " codesniffer ............................ Run CodeSniffer except for the FileCommentSniff"
@echo " codesniffer_year ....................... Run CodeSniffer including the FileCommentSniff"
@echo " codebeautifier ......................... Run CodeBeautifier"
help-test:
@echo " test ......................... Execute unit, integration and extension tests"
@echo " test-unit .................... Run OntoWiki unit tests"
@echo " test-integration-virtuoso .... Run OntoWiki integration tests with virtuoso"
@echo " test-integration-mysql ....... Run OntoWiki integration tests with mysql"
@echo " test-extensions .............. Run tests for extensions"
getcomposer:
curl -o composer.phar "https://getcomposer.org/composer.phar"
php composer.phar self-update
install: deploy
ifdef COMPOSER
deploy: directories clean composer-install
else
deploy: getcomposer
make deploy
endif
clean:
rm -rf cache/* logs/* libraries/*
directories: clean
mkdir -p logs cache
chmod 777 logs cache extensions
ifdef COMPOSER
composer-install: #add difference for user and dev (with phpunit etc and without)
$(COMPOSER) install
else
composer-install:
@echo
@echo
@echo "!!! make $@ failed !!!"
@echo
@echo "Sorry, there doesn't seem to be a PHP composer (dependency manager for PHP) on your system!"
@echo "Please have a look at http://getcomposer.org/ for further information,"
@echo "or just run 'make getcomposer' to download the composer locally"
@echo "and run 'make $@' again"
endif
# test stuff
devenv:
git clone "https://github.com/pfrischmuth/ontowiki-devenv.git" devenv
cp -i devenv/config.ini.dist ./config.ini
cp -i devenv/config-test.ini.dist ./application/tests/config.ini
test-directories:
rm -rf application/tests/cache application/tests/unit/cache application/tests/integration/cache
mkdir -p application/tests/cache application/tests/unit/cache application/tests/integration/cache
test-unit: test-directories
$(PHPUNIT) --testsuite "OntoWiki Unit Tests"
test-integration-virtuoso: test-directories
EF_STORE_ADAPTER=virtuoso $(PHPUNIT) --testsuite "OntoWiki Virtuoso Integration Tests"
test-integration-mysql: test-directories
EF_STORE_ADAPTER=zenddb $(PHPUNIT) --testsuite "OntoWiki Virtuoso Integration Tests"
test-extensions: #directories
$(PHPUNIT) --testsuite "OntoWiki Extensions Tests"
test:
make test-unit
@echo ""
@echo "-----------------------------------"
@echo ""
make test-integration-virtuoso
@echo ""
@echo "-----------------------------------"
@echo ""
make test-integration-mysql
@echo ""
@echo "-----------------------------------"
@echo ""
make test-extensions
odbctest:
@application/scripts/odbctest.php
# packaging
debianize:
rm extensions/markdown/parser/License.text
rm extensions/markdown/parser/PHP_Markdown_Readme.txt
rm extensions/markdown/parser/markdown.php
rm extensions/queries/resources/codemirror/LICENSE
rm extensions/themes/silverblue/scripts/libraries/jquery-1.9.1.js
rm libraries/RDFauthor/libraries/jquery.js
rm Makefile
@echo "now do: cp -R application/scripts/debian debian"
# #### config ####
codesniffer:
$(PHPCS) -p
codebeautifier:
$(PHPCBF)
# other stuff
list-events:
@grep -R "new Erfurt_Event" * 2> /dev/null | sed "s/.*new Erfurt_Event('//;s/');.*//" | sort -u
================================================
FILE: README.md
================================================
# OntoWiki
Note: This project is not under active development anymore. See [this issue](https://github.com/AKSW/OntoWiki/issues/441) for more details.
[](https://travis-ci.org/AKSW/OntoWiki/) [](https://packagist.org/packages/aksw/ontowiki) [](https://packagist.org/packages/aksw/ontowiki) [](https://packagist.org/packages/aksw/ontowiki) [](https://packagist.org/packages/aksw/ontowiki)
[](https://docs.ontowiki.net) [](http://api.ontowiki.net/)

## Introduction
is a tool providing support for agile, distributed knowledge engineering scenarios.
OntoWiki facilitates the visual presentation of a knowledge base as an information map, with different views on instance data.
It enables intuitive authoring of semantic content.
It fosters social collaboration aspects by keeping track of changes, allowing to comment and discuss every single part of a knowledge base.
Other remarkable features are:
* OntoWiki is a Linked Data Server for you data as well as a Linked Data client to fetch additional data from the web
* OntoWiki is a Semantic Pingback Client in order to receive and send back-linking request as known from the blogosphere.
* OntoWiki is backend independent, which means you can save your data on a MySQL database as well as on a Virtuoso Triple Store.
* OntoWiki is easily extendible by you, since it features a sophisticated Extension System.
## Installation/Update
If you are updating OntoWiki, please don't forget to run `make install`.
If `make install` fails, you might also have to run `make getcomposer` once before run `make deploy` again.
For further installation instructions please have a look at our [wiki](https://docs.ontowiki.net/) (might be outdated in some parts).
## Screenshot / Webinar
Below is a screenshot showing OntoWiki in editing mode.
For a longer visual presentation you can watch our [webinar@youtube](http://www.youtube.com/watch?v=vP1UDKeZsQk)
(thanks to Phil and the Semantic Web company).

## Documentation
The Documentation is hosted at https://docs.ontowiki.net/ . If you find errors or think we should add something to it
you are free to fork https://github.com/AKSW/docs.ontowiki.net and send us a pull requst with your changes.
## License
OntoWiki is licensed under the [GNU General Public License Version 2, June 1991](http://www.gnu.org/licenses/gpl-2.0.txt) (license document is in the application subfolder).
================================================
FILE: application/Bootstrap.php
================================================
*/
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
/**
* Initializes the the extension manager which in turn scans
* for components, modules, plugins and wrapper and registers them.
*
* @since 0.9.5
*/
public function _initExtensionManager()
{
// require Front controller
$this->bootstrap('frontController');
$frontController = $this->getResource('frontController');
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
//NOTICE: i swtiched loading of erfurt and session
//because serialized erfurt objects in the session need constants defined in erfurt
//is this ok?
Erfurt_Wrapper_Registry::reset();
// require Erfurt
$this->bootstrap('Erfurt');
// apply session configuration settings
if (isset($config->session)) {
$this->applySessionConfig($config->session);
}
// require Session
$this->bootstrap('Session');
// require Dispatcher
$this->bootstrap('Dispatcher');
$dispatcher = $this->getResource('Dispatcher');
// require OntoWiki
$this->bootstrap('OntoWiki');
$ontoWiki = $this->getResource('OntoWiki');
// require Translate
$this->bootstrap('Translate');
$translate = $this->getResource('Translate');
// require View
$this->bootstrap('View');
$view = $this->getResource('View');
// make sure router is bootstrapped
$this->bootstrap('Router');
// set view
$ontoWiki->view = $view;
$extensionPath = ONTOWIKI_ROOT
. $config->extensions->base;
$extensionPathBase = $config->staticUrlBase
. $config->extensions->base;
$extensionManager = new OntoWiki_Extension_Manager($extensionPath);
$extensionManager->setTranslate($translate)
->setComponentUrlBase($extensionPathBase);
// register component controller directories
foreach ($extensionManager->getComponents() as $extensionName => $extensionConfig) {
$frontController->addControllerDirectory($extensionConfig->path, '_component_' . $extensionName);
}
// make extension manager available to dispatcher
$dispatcher = $frontController->getDispatcher();
$dispatcher->setExtensionManager($extensionManager);
// keep extension manager in OntoWiki
$ontoWiki->extensionManager = $extensionManager;
// actionhelper
Zend_Controller_Action_HelperBroker::addPrefix('OntoWiki_Controller_ActionHelper_');
Zend_Controller_Action_HelperBroker::addHelper(new OntoWiki_Controller_ActionHelper_List());
return $extensionManager;
}
/**
* Loads the application config file
*
* @since 0.9.5
*/
public function _initConfig()
{
// load default application configuration file
try {
$config = new Zend_Config_Ini(APPLICATION_PATH . 'config/default.ini', 'default', true);
} catch (Zend_Config_Exception $e) {
throw $e;
}
// load user application configuration files
$tryDistConfig = false;
try {
$privateConfig = new Zend_Config_Ini(ONTOWIKI_ROOT . 'config.ini', 'private', true);
$config->merge($privateConfig);
} catch (Zend_Config_Exception $e) {
$tryDistConfig = true;
}
if ($tryDistConfig === true) {
try {
$privateConfig = new Zend_Config_Ini(ONTOWIKI_ROOT . 'config.ini.dist', 'private', true);
$config->merge($privateConfig);
} catch (Zend_Config_Exception $e) {
$message = '
OntoWiki can not find a proper configuration.
' . PHP_EOL
. '
Maybe you have to copy and modify the distributed '
. 'config.ini.dist file?
'. PHP_EOL
. 'Error Details'
. $e->getMessage() . '';
throw new OntoWiki_Exception($message);
}
}
// normalize path names
$config->themes->path = rtrim($config->themes->path, '/\\') . '/';
$config->themes->default = rtrim($config->themes->default, '/\\') . '/';
$config->extensions->base = rtrim($config->extensions->base, '/\\') . '/';
if (false === defined('EXTENSION_PATH')) {
define('EXTENSION_PATH', $config->extensions->base);
}
$config->extensions->legacy = EXTENSION_PATH . rtrim($config->extensions->legacy, '/\\') . '/';
$config->languages->path = EXTENSION_PATH . rtrim($config->languages->path, '/\\') . '/';
$config->libraries->path = rtrim($config->libraries->path, '/\\') . '/';
$config->cache->path = rtrim($config->cache->path, '/\\') . '/';
$config->log->path = rtrim($config->log->path, '/\\') . '/';
// support absolute path
$matches = array();
if (!(preg_match('/^(\w:[\/|\\\\]|\/)/', $config->cache->path, $matches) === 1)) {
$config->cache->path = ONTOWIKI_ROOT . $config->cache->path;
}
// set path variables
$rewriteBase = substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], BOOTSTRAP_FILE));
// set protocol and read headers sent by proxies
$protocol = 'http';
if (isset($_SERVER['X-Forwarded-Protocol'])) {
$protocol = strtolower($_SERVER['X-Forwarded-Protocol']);
} else if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
$protocol = strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']);
} else if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
$protocol = 'https';
}
if (isset($_SERVER['HTTP_HOST'])) {
$httpHost = $_SERVER['HTTP_HOST'];
} else {
$httpHost = 'localhost';
}
$urlBase = sprintf(
'%s://%s%s',
$protocol,
$httpHost,
$rewriteBase
);
// construct URL variables
$config->host = parse_url($urlBase, PHP_URL_HOST);
$config->urlBase = rtrim($urlBase . (ONTOWIKI_REWRITE ? '' : BOOTSTRAP_FILE), '/\\') . '/';
$config->staticUrlBase = rtrim($urlBase, '/\\') . '/';
$config->themeUrlBase = $config->staticUrlBase
. $config->themes->path
. $config->themes->default;
$config->libraryUrlBase = $config->staticUrlBase
. $config->libraries->path;
//check if log.level has a valid integer as value
if (!((int)$config->log->level >= 0 && (int)$config->log->level <= 7)) {
$config->log->level = 0;
}
// define constants for development/debugging
if (isset($config->debug) && (boolean)$config->debug) {
// display errors
error_reporting(E_ALL | E_STRICT);
ini_set('display_errors', 'On');
// enable debugging options
if (false === defined('_OWDEBUG')) {
define('_OWDEBUG', 1);
}
// log everything
$config->log->enabled = true;
$config->log->level = 7;
}
return $config;
}
/**
* apply session config
*
* @param Zend_Config $sessionConfig Session configuration settings
*/
protected function applySessionConfig($sessionConfig)
{
$cookieParams = array(
'lifetime' => isset($sessionConfig->lifetime) ? $sessionConfig->lifetime : 0,
'path' => isset($sessionConfig->path) ? $sessionConfig->path : '/',
'domain' => isset($sessionConfig->domain) ? $sessionConfig->domain : '',
'secure' => isset($sessionConfig->secure) ? (bool)$sessionConfig->secure : false,
'httpOnly' => isset($sessionConfig->httpOnly) ? (bool)$sessionConfig->httpOnly : false
);
call_user_func_array('session_set_cookie_params', $cookieParams);
}
/**
* Initializes the modified Zend_Conroller_Dispatcher to allow for
* pluggable controllers
*
* @since 0.9.5
*/
public function _initDispatcher()
{
// require Front controller
$this->bootstrap('frontController');
$frontController = $this->getResource('frontController');
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
$dispatcher = new OntoWiki_Dispatcher(array('url_base' => $config->urlBase));
$dispatcher->setControllerDirectory(APPLICATION_PATH . 'controllers');
$frontController->setDispatcher($dispatcher);
return $dispatcher;
}
/**
* Initializes the Erfurt framework
*
* @since 0.9.5
*/
public function _initErfurt()
{
$erfurt = null;
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
// require OntoWiki
$this->bootstrap('OntoWiki');
$ontoWiki = $this->getResource('OntoWiki');
// require Logger, since Erfurt logger should write into OW logs dir
$this->bootstrap('Logger');
// Reset the Erfurt app for testability... needs to be refactored.
Erfurt_App::reset();
try {
$erfurt = Erfurt_App::getInstance(false)->start($config);
} catch (Erfurt_Exception $ee) {
throw new OntoWiki_Exception('Error loading Erfurt framework: ' . $ee->getMessage());
} catch (Exception $e) {
throw new OntoWiki_Exception('Unexpected error: ' . $e->getMessage());
}
// make available
$ontoWiki->erfurt = $erfurt;
return $erfurt;
}
/**
* Initializes the event dispatcher
*
* @since 0.9.5
*/
public function _initEventDispatcher()
{
// load event dispatcher for Erfurt and OntoWiki events
$eventDispatcher = Erfurt_Event_Dispatcher::getInstance();
return $eventDispatcher;
}
/**
* Loads logging capability
*
* @since 0.9.5
*/
public function _initLogger()
{
// require config
$this->bootstrap('Config');
$config = $this->getResource('Config');
// support absolute path
if (!(preg_match('/^(\w:[\/|\\\\]|\/)/', $config->log->path) === 1)) {
// prepend OntoWiki root for relative paths
$config->log->path = ONTOWIKI_ROOT . $config->log->path;
}
// initialize logger
$writer = null;
if (is_writable($config->log->path) && ((boolean)$config->log->enabled == true)) {
$levelFilter = new Zend_Log_Filter_Priority((int)$config->log->level, '<=');
$logName = $config->log->path . 'ontowiki';
// Check whether log can be created with $logName... otherwise append a number.
// This needs to be done, since logs may be created by other processes (e.g. with
// testing) and thus can't be opened anymore.
$writer = null;
for ($i = 0; $i < 10; ++$i) {
try {
$fullLogName = $logName;
if ($i > 0) {
$fullLogName .= '_' . $i;
}
$fullLogName .= '.log';
$writer = new Zend_Log_Writer_Stream($fullLogName);
if (null !== $writer) {
break;
}
} catch (Zend_Log_Exception $e) {
// Nothing to do... just continue
}
}
if (null !== $writer) {
$logger = new Zend_Log($writer);
$logger->addFilter($levelFilter);
return $logger;
}
}
// fallback to NULL logger
$writer = new Zend_Log_Writer_Null();
$logger = new Zend_Log($writer);
return $logger;
}
/**
* Initializes the navigation
*
* @since 0.9.5
*/
public function _initNavigation()
{
// require Session
$this->bootstrap('Session');
$session = $this->getResource('Session');
$this->bootstrap('Request');
$request = $this->getResource('Request');
$this->bootstrap('Config');
$config = $this->getResource('Config');
// get current action name
$currentAction = $request->getActionName();
// is current action a default action?
if ($currentAction == 'properties' || $currentAction == 'instances') {
// save it to session
$session->lastRoute = $currentAction;
}
// get last route or default
$route = isset($session->lastRoute) ? $session->lastRoute : $config->route->default->name;
// register with navigation
if (isset($config->routes->{$route})) {
extract($config->routes->{$route}->defaults->toArray());
// and add last routed component
OntoWiki::getInstance()->getNavigation()->register(
'index',
array(
'route' => $route,
'controller' => $controller,
'action' => $action,
'name' => ucfirst($route),
'priority' => 0
)
);
}
}
/**
* Initializes the OntoWiki main class
*
* @since 0.9.5
*/
public function _initOntoWiki()
{
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
OntoWiki::reset();
$ontoWiki = OntoWiki::getInstance();
$ontoWiki->setBootstrap($this);
$ontoWiki->language = isset($config->languages->locale) ? $config->languages->locale : null;
$ontoWiki->config = $config;
return $ontoWiki;
}
public function _initPlugins()
{
// require front controller
$this->bootstrap('frontController');
$frontController = $this->getResource('frontController');
// Needs to be done first!
$frontController->registerPlugin(new OntoWiki_Controller_Plugin_HttpAuth(), 1);
$frontController->registerPlugin(new OntoWiki_Controller_Plugin_SetupHelper(), 2);
//needs to be done after SetupHelper
$frontController->registerPlugin(new OntoWiki_Controller_Plugin_ListSetupHelper(), 3);
}
/**
* Initializes the request object
*
* @since 0.9.5
*/
public function _initRequest()
{
$this->bootstrap('FrontController');
$frontController = $this->getResource('FrontController');
$this->bootstrap('Router');
$router = $this->getResource('Router');
$request = new OntoWiki_Request();
$frontController->setRequest($request);
$router->route($request);
return $request;
}
/**
* Initializes the router
*
* @since 0.9.5
*/
public function _initRouter()
{
// require front controller
$this->bootstrap('frontController');
$frontController = $this->getResource('frontController');
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
$router = $frontController->getRouter();
$router->addConfig($config->routes);
return $router;
}
/**
* Initializes the session and loads session variables
*
* @since 0.9.5
*/
public function _initSession()
{
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
// require Config
$this->bootstrap('OntoWiki');
$ontoWiki = $this->getResource('OntoWiki');
// init session
$sessionKey = 'ONTOWIKI' . (isset($config->session->identifier) ? $config->session->identifier : '');
$session = new Zend_Session_Namespace($sessionKey);
// define the session key as a constant for global reference
if (false === defined('_OWSESSION')) {
define('_OWSESSION', $sessionKey);
}
// inject session vars into OntoWiki
if (array_key_exists('sessionVars', $this->_options['bootstrap'])) {
$ontoWiki->setSessionVars((array)$this->_options['bootstrap']['sessionVars']);
}
// make available
$ontoWiki->session = $session;
return $session;
}
/**
* Initializes the toolbar
*
* @since 0.9.5
*/
public function _initToolbar()
{
$this->bootstrap('Config');
$config = $this->getResource('Config');
$this->bootstrap('Translate');
$translate = $this->getResource('Translate');
// configure toolbar
$toolbar = OntoWiki_Toolbar::getInstance();
$toolbar->setThemeUrlBase($config->themeUrlBase)
->setTranslate($translate);
return $toolbar;
}
/**
* Loads the translation
*
* @since 0.9.5
*/
public function _initTranslate()
{
$this->bootstrap('Config');
$config = $this->getResource('Config');
// setup translation cache
if ((boolean)$config->cache->translation) {
// set translation cache
Zend_Translate::setCache($this->getResource('Erfurt')->getCache());
}
// set up translations
$options = array(
// scan locale from directories
'scan' => Zend_Translate::LOCALE_DIRECTORY,
// don't emit notices
'disableNotices' => true
);
$translate = new Zend_Translate('csv', ONTOWIKI_ROOT . $config->languages->path, null, $options);
try {
$translate->setLocale($config->languages->locale);
} catch (Zend_Translate_Exception $e) {
$config->languages->locale = 'en';
$translate->setLocale('en');
}
return $translate;
}
/**
* Authenticates the current user or Anonymous with Erfurt
*
* @since 0.9.5
*/
public function _initUser()
{
$user = null;
// require Erfurt
$this->bootstrap('Erfurt');
$erfurt = $this->getResource('Erfurt');
// get logged in user
$auth = $erfurt->getAuth();
if ($auth->hasIdentity()) {
$user = $auth->getIdentity();
}
if (null === $user) {
// authenticate anonymous user
$erfurt->authenticate('Anonymous', '');
$user = $auth->getIdentity();
}
return $user;
}
/**
* Sets up the view environment
*
* @since 0.9.5
*/
public function _initView()
{
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
// require Config
$this->bootstrap('Translate');
$translate = $this->getResource('Translate');
// standard template path
$defaultTemplatePath = ONTOWIKI_ROOT
. 'application/views/templates';
// path for theme template
$themeTemplatePath = ONTOWIKI_ROOT
. $config->themes->path
. $config->themes->default
. 'templates';
$viewOptions = array(
'use_module_cache' => (bool)$config->cache->modules,
'cache_path' => $config->cache->path,
'lang' => $config->languages->locale
);
// init view
$view = new OntoWiki_View($viewOptions, $translate);
$view->addScriptPath($defaultTemplatePath) // default templates
->addScriptPath($themeTemplatePath) // theme templates override default ones
->addScriptPath($config->extensions->base) // extension templates
->setEncoding($config->encoding)
->setHelperPath(ONTOWIKI_ROOT . 'application/classes/OntoWiki/View/Helper', 'OntoWiki_View_Helper');
// set Zend_View to emit notices in debug mode
$view->strictVars(defined('_OWDEBUG'));
// init view renderer action helper
$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
Zend_Controller_Action_HelperBroker::addHelper($viewRenderer);
$themeLayoutTemplate = $themeTemplatePath
. DIRECTORY_SEPARATOR
. 'layouts'
. DIRECTORY_SEPARATOR
. 'layout.phtml';
$layoutPath = $defaultTemplatePath . DIRECTORY_SEPARATOR . 'layouts';
if (is_readable($themeLayoutTemplate)) {
$layoutPath = $themeTemplatePath . DIRECTORY_SEPARATOR . 'layouts';
}
// initialize layout
Zend_Layout::startMvc(
array(
// for layouts we use the default path
'layoutPath' => $layoutPath
)
);
return $view;
}
}
================================================
FILE: application/LICENSE.txt
================================================
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
================================================
FILE: application/classes/OntoWiki/Component/Exception.php
================================================
*/
class OntoWiki_Component_Exception extends OntoWiki_Exception
{
}
================================================
FILE: application/classes/OntoWiki/Component/Helper.php
================================================
*/
class OntoWiki_Component_Helper
{
/**
* The component's file system root directory
*
* @var string
*/
protected $_componentRoot = null;
/**
* The components URL base
*
* @var string
*/
protected $_componentUrlBase = null;
/**
* OntoWiki Application config
*
* @var Zend_Config
*/
protected $_config;
/**
* The component private config
*
* @var Zend_Config
*/
protected $_privateConfig;
/**
* OntoWiki Application
*
* @var OntoWiki
*/
protected $_owApp;
/**
* Constructor
*
* @param OntoWiki_Component_Manager $componentManager
*/
public function __construct($config)
{
$this->_owApp = OntoWiki::getInstance();
$this->_config = $this->_owApp->getConfig();
$this->_privateConfig = isset($config->private) ? $config->private : new Zend_Config(array(), true);
}
/**
* Overwritten in subclasses
*/
public function init()
{
}
public function getPrivateConfig()
{
return $this->_privateConfig;
}
public function getComponentRoot()
{
$componentName = strtolower(str_replace('Helper', '', get_class($this)));
// set component root dir
$this->_componentRoot = $this->_owApp->extensionManager->getComponentPath() . $componentName . '/';
return $this->_componentRoot;
}
public function getComponentUrlBase()
{
$componentName = strtolower(str_replace('Helper', '', get_class($this)));
// set component root url
$this->_componentUrlBase
= $this->_config->staticUrlBase . $this->_config->extensions->base . $componentName . '/';
return $this->_componentUrlBase;
}
}
================================================
FILE: application/classes/OntoWiki/Controller/ActionHelper/List.php
================================================
_owApp = OntoWiki::getInstance();
if (!isset($this->_owApp->session->managedLists)) {
$this->_owApp->session->managedLists = array();
}
}
/**
*
* @return OntoWiki_Model_Instances
*/
public function getLastList()
{
$name = $this->_owApp->session->lastList;
if (isset($this->_owApp->session->managedLists)) {
$lists = $this->_owApp->session->managedLists;
if (key_exists($name, $lists)) {
return $lists[$name];
}
}
return null;
}
/**
*
* @return string
*/
public function getLastListName()
{
return $this->_owApp->session->lastList;
}
/**
*
* @return bool
*/
public function listExists($name)
{
$lists = $this->_owApp->session->managedLists;
if (key_exists($name, $lists)) {
return true;
}
return false;
}
/**
*
* @return OntoWiki_Model_Instances
*/
public function getList($name)
{
$lists = $this->_owApp->session->managedLists;
if (key_exists($name, $lists)) {
return $lists[$name];
}
throw new InvalidArgumentException('list was not found. check with listExists() first');
}
/**
* Render a list, add it to the cache and add it to the current view
*
* @param $listName string with a listname
* @param $list OntoWiki_Model_Instances a list of resources
* @param $view the current view to which the list should be added
* @param $mainTemplate the template to use for rendering the list
* @param $other array of other values available to the template
* @param $returnOutput true|false if false, the list is rendered directly to the view else the
* rendered list is returned
* @return the rendered list if $returnOutput is true
*/
public function addListPermanently(
$listName,
OntoWiki_Model_Instances $list,
Zend_View_Interface $view,
$mainTemplate = 'list_std_main',
$other = null,
$returnOutput = false
) {
$this->updateList($listName, $list, true);
return $this->addList($listName, $list, $view, $mainTemplate, $other, $returnOutput);
}
/**
* Render a list and add it to the current view
*
* @param $listName string with a listname
* @param $list OntoWiki_Model_Instances a list of resources
* @param $view the current view to which the list should be added
* @param $mainTemplate the template to use for rendering the list
* @param $other array of other values available to the template
* @param $returnOutput true|false if false, the list is rendered directly to the view else the
* rendered list is returned
* @return the rendered list if $returnOutput is true
*/
public function addList(
$listName,
OntoWiki_Model_Instances $list,
Zend_View_Interface $view,
$mainTemplate = 'list_std_main',
$other = null,
$returnOutput = false
) {
if ($other === null) {
$other = new stdClass();
}
$renderedList = $view->partial(
'partials/list.phtml',
array(
'listName' => $listName,
'instances' => $list,
'mainTemplate' => $mainTemplate,
'other' => $other
)
);
$this->_owApp->session->lastList = $listName;
if ($returnOutput) {
return $renderedList;
} else {
$this->getResponse()->append('default', $renderedList);
}
}
public function updateList($name, OntoWiki_Model_Instances $list, $setLast = false)
{
$lists = $this->_owApp->session->managedLists;
$lists[$name] = $list;
$this->_owApp->session->managedLists = $lists;
if ($setLast) {
$this->_owApp->session->lastList = $name;
}
}
public function getAllLists()
{
return $this->_owApp->session->managedLists;
}
public function removeAllLists()
{
$this->_owApp->session->managedLists = array();
}
public function removeList($name)
{
$lists = $this->_owApp->session->managedLists;
if (key_exists($name, $lists)) {
unset($lists[$name]);
}
throw new InvalidArgumentException('list was not found. check with listExists() first');
}
}
================================================
FILE: application/classes/OntoWiki/Controller/Base.php
================================================
*/
class OntoWiki_Controller_Base extends Zend_Controller_Action
{
/**
* OntoWiki Application
*
* @var OntoWiki
*/
protected $_owApp = null;
/**
* OntoWiki Application config
*
* @var Zend_Config
*/
protected $_config = null;
/**
* The session store
*
* @var Zend_Session
*/
protected $_session = null;
/**
* Erfurt App
*
* @var Erfurt_App
*/
protected $_erfurt = null;
/**
* The Erfurt event dispatcher
*
* @var Erfurt_Event_Dispatcher
*/
protected $_eventDispatcher = null;
/**
* Time before the conroller is launched
*
* @var float
*/
private $_preController;
/**
* Constructor
*/
public function init()
{
/**
* @trigger onBeforeInitController
* Triggered before a controller of class OntoWiki_Controller_Base (or derived)
* is initialized.
*/
$event = new Erfurt_Event('onBeforeInitController');
$eventResult = $event->trigger();
// init controller variables
$this->_owApp = OntoWiki::getInstance();
$this->_config = $this->_owApp->config;
$this->_session = $this->_owApp->session;
$this->_erfurt = $this->_owApp->erfurt;
$this->_eventDispatcher = Erfurt_Event_Dispatcher::getInstance();
// set important script variables
$this->view->themeUrlBase = $this->_config->themeUrlBase;
$this->view->urlBase = $this->_config->urlBase;
$this->view->staticUrlBase = $this->_config->staticUrlBase;
$this->view->libraryUrlBase = $this->_config->staticUrlBase . 'libraries/';
$graph = $this->_owApp->selectedModel;
if ($graph instanceof Erfurt_Rdf_Model) {
if ($graph->isEditable()) {
$this->view->placeholder('update')->set(
array(
'defaultGraph' => $graph->getModelIri(),
'queryEndpoint' => $this->_config->urlBase . 'sparql/',
'updateEndpoint' => $this->_config->urlBase . 'update/'
)
);
}
}
// check config for additional styles
if ($stylesExtra = $this->_config->themes->styles) {
$this->view->themeExtraStyles = $stylesExtra->toArray();
} else {
$this->view->themeExtraStyles = array();
}
// disable layout for Ajax requests
if ($this->_request->isXmlHttpRequest()) {
$this->_helper->layout()->disableLayout();
}
// initialize view helpers
$this->view->headTitle($this->_config->title->prefix, 'SET');
$this->view->headTitle()->setSeparator($this->_config->title->separator);
$this->view->headMeta()->setHttpEquiv('Content-Type', 'text/html; charset=' . $this->_config->encoding);
$this->view->headMeta()->setName('generator', 'OntoWiki — Collaborative Knowledge Engineering');
// RDFauthor view configuration
$viewMode = isset($this->_config->rdfauthor->viewmode) ? $this->_config->rdfauthor->viewmode : 'inline';
// inject JSON variables into view
$this->view->jsonVars
= '
var urlBase = "' . $this->_config->urlBase . '";
var themeUrlBase = "' . $this->_config->themeUrlBase . '";
var _OWSESSION = "' . _OWSESSION . '";
var RDFAUTHOR_BASE = "' . $this->_config->staticUrlBase . 'libraries/RDFauthor/";
var RDFAUTHOR_VIEW_MODE = "' . $viewMode . '";' . PHP_EOL;
if (defined('_OWDEBUG')) {
$this->view->jsonVars .= ' var RDFAUTHOR_DEBUG = 1;';
}
if ($this->_owApp->selectedModel) {
$this->view->jsonVars
.= '
var selectedGraph = {
URI: "' . (string)$this->_owApp->selectedModel . '",
title: ' . json_encode((string)$this->_owApp->selectedModel->getTitle()) . ',
editable: ' . ($this->_owApp->selectedModel->isEditable() ? 'true' : 'false') . '
};
var RDFAUTHOR_DEFAULT_GRAPH = "' . (string)$this->_owApp->selectedModel . '";' . PHP_EOL;
}
if ($this->_owApp->selectedResource) {
$this->view->jsonVars
.= '
var selectedResource = {
URI: "' . (string)$this->_owApp->selectedResource . '",
title: ' . json_encode((string)$this->_owApp->selectedResource->getTitle()) . ',
graphURI: "' . (string)$this->_owApp->selectedModel . '"
};
var RDFAUTHOR_DEFAULT_SUBJECT = "' . (string)$this->_owApp->selectedResource . '";' . PHP_EOL;
}
// set ratio between left bar and main window
if (isset($this->_session->sectionRation)) {
$this->view->headScript()->appendScript(
'var sectionRatio = ' . $this->_session->sectionRation . ';'
);
}
if (isset($this->_config->meta)) {
if (isset($this->_config->meta->Keywords)) {
$this->view->metaKeywords = $this->_config->meta->Keywords;
}
if (isset($this->_config->meta->Description)) {
$this->view->metaDescription = $this->_config->meta->Description;
}
}
/**
* @trigger onAfterInitController
* Triggered after a controller from class OntoWiki_Controller_Base (or derived)
* has been initialized.
*/
$event = new Erfurt_Event('onAfterInitController');
$event->response = $this->_response;
$eventResult = $event->trigger();
}
/**
* Zend pre-dispatch hook.
*
* Executed before dispatching takes place.
*/
public function preDispatch()
{
// log time before dispatch
$this->_preController = microtime(true);
// render main modules
if (!$this->view->has('main.sidewindows') && !$this->_request->isXmlHttpRequest()) {
$this->view->placeholder('main.sidewindows')->append($this->view->modules('main.sidewindows'));
}
}
/**
* Zend post-dispatch hook.
*
* Executed after dispatching has taken place.
*/
public function postDispatch()
{
// log dispatch time
$this->_owApp->logger->info(
sprintf(
'Dispatching %s/%s: %d ms',
$this->_request->getControllerName(),
$this->_request->getActionName(),
(microtime(true) - $this->_preController) * 1000
)
);
// catch redirect
if ($this->_request->has('redirect-uri')) {
$redirectUri = urldecode($this->_request->getParam('redirect-uri'));
$front = Zend_Controller_Front::getInstance();
if ('' !== $front->getBaseUrl()) {
$prependBase = (false === strpos($redirectUri, $front->getBaseUrl()));
} else {
$prependBase = true;
}
$options = array('prependBase' => $prependBase);
$this->_redirect($redirectUri, $options);
}
if (strlen($this->view->placeholder('main.window.title')->toString()) > 0) {
$this->view->headTitle($this->view->placeholder('main.window.title')->toString());
}
}
/**
* Returns a parameter from the current request and expands its URI
* using the local namespace table. It also strips slashes if
* magic_quotes_gpc is turned on in PHP.
*
* @param string $name the name of the parameter
* @param boolean $expandNamespace Whether to expand the namespace or not
*
* @deprecated 0.9.5, use OntoWiki_Request::getParam() instead
*
* @return mixed the parameter or null if not found
*/
public function getParam($name, $expandNamespace = false)
{
$value = $this->_request->getParam($name);
if ($expandNamespace) {
$value = OntoWiki_Utils::expandNamespace($value);
}
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
return $value;
}
/**
* Adds a module context which the controller provides
*
* @param string $moduleContext The context name
*/
public function addModuleContext($moduleContext)
{
if (!$this->_request->isXmlHttpRequest()) {
$moduleContent = $this->view->modules($moduleContext);
$this->view->placeholder('main.window.innerwindows')->append($moduleContent);
}
}
/**
* Clones the current view object and returns a new view
* object with the same configuration but all variables cleared.
*
* @return OntoWiki_View
*/
public function cloneView()
{
$view = clone $this->view;
$view->clearVars();
return $view;
}
/**
* tests if there is a selected model and appends an error message
* (optional) to the message queue
*
* @param boolean $appendMessage append a error message or not (default: true)
* @since 0.9.9
* @return boolean
*/
public function isModelSelected($appendMessage = true)
{
if ($this->_owApp->selectedModel === null) {
if ($appendMessage) {
$this->_owApp->appendMessage(
new OntoWiki_Message(
$this->view->_('No model selected.'),
OntoWiki_Message::ERROR
)
);
}
return false;
} else {
return true;
}
}
/**
* tests if there is an editable selected model and appends an error message
* (optional) to the message queue
*
* @param boolean $appendMessage append a error message or not (default: true)
* @since 0.9.9
* @return boolean
*/
public function isSelectedModelEditable($appendMessage = true)
{
if (!$this->isModelSelected($appendMessage)) {
return false;
} else {
if (!$this->_owApp->selectedModel->isEditable()) {
if ($appendMessage) {
$this->_owApp->appendMessage(
new OntoWiki_Message(
$this->view->_('No write permissions on this model.'),
OntoWiki_Message::ERROR
)
);
}
return false;
} else {
return true;
};
}
}
}
================================================
FILE: application/classes/OntoWiki/Controller/Component.php
================================================
*/
class OntoWiki_Controller_Component extends OntoWiki_Controller_Base
{
/**
* The component's file system root directory
*
* @var string
*/
protected $_componentRoot = null;
/**
* The components URL base
*
* @var string
*/
protected $_componentUrlBase = null;
/**
* The component helper object
*
* @var OntoWiki_Component_Helper
*/
protected $_componentHelper = null;
/**
* The component private config
*
* @var array
*/
protected $_privateConfig = null;
/**
* Constructor
*/
public function init()
{
parent::init();
$cm = $this->_owApp->extensionManager;
$name = $this->_request->getControllerName();
// set component specific template path
if ($tp = $cm->getComponentTemplatePath($name)) {
$this->view->addScriptPath($tp);
}
// set component specific helper path
if ($hp = $cm->getComponentHelperPath($name)) {
$this->view->addHelperPath($hp, ucfirst($name) . '_View_Helper_');
}
// set private config
if ($pc = $cm->getPrivateConfig($name)) {
$this->_privateConfig = $pc;
}
// set component root dir
$this->_componentRoot = $cm->getExtensionPath()
. $name
. '/';
// set component root url
$this->_componentUrlBase = $this->_config->staticUrlBase
. $this->_config->extensions->base
. $name
. '/';
}
/**
* Returns the helper object associated with the component.
*
* @throws OntoWiki_Component_Exception if the component has no helper defined.
* @return OntoWiki_Component_Helper
*/
public function getComponentHelper()
{
if (null === $this->_componentHelper) {
$name = $this->_request->getControllerName();
$extensionManager = $this->_owApp->extensionManager;
$this->_componentHelper = $extensionManager->getComponentHelper($name);
}
return $this->_componentHelper;
}
}
================================================
FILE: application/classes/OntoWiki/Controller/Exception.php
================================================
*/
class OntoWiki_Controller_Exception extends OntoWiki_Exception
{
}
================================================
FILE: application/classes/OntoWiki/Controller/Plugin/HttpAuth.php
================================================
*/
class OntoWiki_Controller_Plugin_HttpAuth extends Zend_Controller_Plugin_Abstract
{
/**
* Retieves user credentials from the current request and tries to
* authenticate the user with Erfurt.
*
* @param Zend_Controller_Request_Abstract $request The current request object
*/
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
if ($credentials = $this->_getAuthHeaderCredentials($request)) {
switch ($credentials['type']) {
case 'basic':
$erfurt = OntoWiki::getInstance()->erfurt;
$logger = OntoWiki::getInstance()->logger;
// authenticate
$authResult = $erfurt->authenticate($credentials['username'], $credentials['password']);
if ($authResult->isValid()) {
$logger = OntoWiki::getInstance()->logger;
$logger->info("User '$credentials[username]' authenticated via HTTP.");
} else {
// if authentication attempt fails, send appropriate headers
$front = Zend_Controller_Front::getInstance();
$response = $front->getResponse();
$response->setRawHeader('HTTP/1.1 401 Unauthorized');
echo 'HTTP/1.1 401 Unauthorized';
return;
}
break;
case 'foaf+ssl':
$adapter = new Erfurt_Auth_Adapter_FoafSsl();
$authResult = $adapter->authenticateWithCredentials($credentials['creds']);
Erfurt_App::getInstance()->getAuth()->setIdentity($authResult);
if ($authResult->isValid()) {
$logger = OntoWiki::getInstance()->logger;
$logger->info('User authenticated with FOAF+SSL via HTTPS.');
}
break;
}
}
}
/**
* Fetches authentication credentials from the current request
*
* @param Zend_Controller_Request_Abstract $request The current request object
*
* @return array
*/
private function _getAuthHeaderCredentials(Zend_Controller_Request_Abstract $request)
{
$authHeader = $request->getHeader('Authorization');
if (is_string($authHeader) && strlen($authHeader) > 0) {
if (strtolower(substr($authHeader, 0, 8)) === 'foaf+ssl') {
$auth = base64_decode(substr($authHeader, 9));
$creds = explode('=', $auth);
foreach ($creds as &$c) {
if (substr($c, 0, 1) === '"') {
$c = substr($c, 1, -1);
}
}
if (count($creds) > 0) {
return array(
'type' => 'foaf+ssl',
'creds' => $creds
);
}
} else {
if (strtolower(substr($authHeader, 0, 5)) === 'basic') {
$auth = base64_decode(substr($authHeader, 6));
$creds = array_filter(explode(':', $auth));
if (count($creds) > 0) {
return array(
'type' => 'basic',
'username' => $creds[0],
'password' => isset($creds[1]) ? $creds[1] : ''
);
}
}
}
}
}
}
================================================
FILE: application/classes/OntoWiki/Controller/Plugin/ListSetupHelper.php
================================================
*/
class OntoWiki_Controller_Plugin_ListSetupHelper extends Zend_Controller_Plugin_Abstract
{
protected $_isSetup = false;
/**
* RouteStartup is triggered before any routing happens.
*/
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
/**
* @trigger onRouteStartup
*/
$event = new Erfurt_Event('onRouteStartup');
$event->trigger();
}
/**
* RouteShutdown is the earliest event in the dispatch cycle, where a
* fully routed request object is available
*/
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
if (isset($request->noListRedirect)) {
return;
}
$ontoWiki = OntoWiki::getInstance();
// TODO: Refactor! The list helper is from an extension! Do not access extensions
// from core code!
if (!Zend_Controller_Action_HelperBroker::hasHelper('List')) {
return;
}
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
// only once and only when possible
if (!$this->_isSetup
&& $ontoWiki->selectedModel != null
&& (isset($request->init)
|| isset($request->instancesconfig)
|| isset($request->s)
|| isset($request->class)
|| isset($request->p)
|| isset($request->limit))
) {
$frontController = Zend_Controller_Front::getInstance();
$store = $ontoWiki->erfurt->getStore();
$resource = $ontoWiki->selectedResource;
$session = $ontoWiki->session;
// when switching to another class:
// reset session vars (regarding the list)
if (isset($request->init)) {
//echo 'kill list session';
// reset the instances object
unset($session->instances);
//reset config from tag explorer
unset($session->cloudproperties);
}
//react on m parameter to set the selected model
if (isset($request->m)) {
try {
$model = $store->getModel($request->getParam('m', null, false));
$ontoWiki->selectedModel = $model;
} catch (Erfurt_Store_Exception $e) {
$model = null;
$ontoWiki->selectedModel = null;
}
}
$list = $listHelper->getLastList();
if ((!isset($request->list)
&& $list == null)
|| isset($request->init)
) {
// instantiate model, that selects all resources
$list = new OntoWiki_Model_Instances($store, $ontoWiki->selectedModel, array());
} else {
// use the object from the session
if (isset($request->list) && $request->list != $listHelper->getLastListName()) {
if ($listHelper->listExists($request->list)) {
$list = $listHelper->getList($request->list);
$ontoWiki->appendMessage(new OntoWiki_Message('reuse list'));
} else {
throw new OntoWiki_Exception(
'your trying to configure a list, but there is no list name specified'
);
}
}
$list->setStore($store); // store is not serialized in session! reset it
}
//local function :)
function _json_decode($string)
{
/* PHP 5.3 DEPRECATED ; REMOVE IN PHP 6.0 */
if (get_magic_quotes_gpc()) {
// add slashes for unicode chars in json
$string = str_replace('\\u', '\\\\u', $string);
$string = stripslashes($string);
}
/* ---- */
return json_decode($string, true);
}
//a shortcut for search param
if (isset($request->s)) {
if (isset($request->instancesconfig)) {
$config = _json_decode($request->instancesconfig);
if (null === $config) {
throw new OntoWiki_Exception(
'Invalid parameter instancesconfig (json_decode failed): ' . $this->_request->setup
);
}
} else {
$config = array();
}
if (!isset($config['filter'])) {
$config['filter'] = array();
}
$config['filter'][] = array(
'action' => 'add',
'mode' => 'search',
'searchText' => $request->s
);
$request->setParam('instancesconfig', json_encode($config));
}
//a shortcut for class param
if (isset($request->class)) {
if (isset($request->instancesconfig)) {
$config = _json_decode($request->instancesconfig);
if (null === $config) {
throw new OntoWiki_Exception(
'Invalid parameter instancesconfig (json_decode failed): ' . $this->_request->setup
);
}
} else {
$config = array();
}
if (!isset($config['filter'])) {
$config['filter'] = array();
}
$config['filter'][] = array(
'action' => 'add',
'mode' => 'rdfsclass',
'rdfsclass' => $request->class
);
$request->setParam('instancesconfig', json_encode($config));
}
//check for change-requests
if (isset($request->instancesconfig)) {
$config = _json_decode($request->instancesconfig);
if (null === $config) {
throw new OntoWiki_Exception('Invalid parameter instancesconfig (json_decode failed)');
}
// TODO is this a bug? why access sort->asc when it is null?
if (isset($config['sort'])) {
if ($config['sort'] == null) {
$list->orderByUri($config['sort']['asc']);
} else {
$list->setOrderProperty($config['sort']['uri'], $config['sort']['asc']);
}
}
if (isset($config['shownProperties'])) {
foreach ($config['shownProperties'] as $prop) {
if ($prop['action'] == 'add') {
$list->addShownProperty($prop['uri'], $prop['label'], $prop['inverse']);
} else {
$list->removeShownProperty($prop['uri'], $prop['inverse']);
}
}
}
if (isset($config['filter'])) {
foreach ($config['filter'] as $filter) {
// set default value for action and mode if they're not assigned
if (!isset($filter['action'])) {
$filter['action'] = 'add';
}
if (!isset($filter['mode'])) {
$filter['mode'] = 'box';
}
if ($filter['action'] == 'add') {
if ($filter['mode'] == 'box') {
$list->addFilter(
$filter['property'],
isset($filter['isInverse']) ? $filter['isInverse'] : false,
isset($filter['propertyLabel']) ? $filter['propertyLabel'] : 'defaultLabel',
$filter['filter'],
isset($filter['value1']) ? $filter['value1'] : null,
isset($filter['value2']) ? $filter['value2'] : null,
isset($filter['valuetype']) ? $filter['valuetype'] : 'literal',
isset($filter['literaltype']) ? $filter['literaltype'] : null,
isset($filter['hidden']) ? $filter['hidden'] : false,
isset($filter['id']) ? $filter['id'] : null,
isset($filter['negate']) ? $filter['negate'] : false
);
} else {
if ($filter['mode'] == 'search') {
$list->addSearchFilter(
$filter['searchText'],
isset($filter['id']) ? $filter['id'] : null
);
} else {
if ($filter['mode'] == 'rdfsclass') {
$list->addTypeFilter(
$filter['rdfsclass'],
isset($filter['id']) ? $filter['id'] : null
);
} else {
if ($filter['mode'] == 'cnav') {
$list->addTripleFilter(
NavigationHelper::getInstancesTriples($filter['uri'], $filter['cnav']),
isset($filter['id']) ? $filter['id'] : null
);
} else {
if ($filter['mode'] == 'query') {
try {
$query = Erfurt_Sparql_Query2::initFromString($filter['query']);
// TODO what the hell is this?!
if (!($query instanceof Exception)) {
$list->addTripleFilter(
$query->getWhere()->getElements(),
isset($filter['id']) ? $filter['id'] : null
);
}
} catch (Erfurt_Sparql_ParserException $e) {
$ontoWiki->appendMessage('the query could not be parsed');
}
}
}
}
}
}
} else {
$list->removeFilter($filter['id']);
}
}
}
if (isset($config['order'])) {
foreach ($config['order'] as $prop) {
if ($prop['action'] == 'set') {
if ($prop['mode'] == 'var') {
$list->setOrderVar($prop['var']);
} else {
$list->setOrderUri($prop['uri']);
}
}
}
}
}
if (isset($request->limit)) { // how many results per page
$list->setLimit($request->limit);
} else {
$list->setLimit(10);
}
if (isset($request->p)) { // p is the page number
$list->setOffset(
($request->p * $list->getLimit()) - $list->getLimit()
);
} else {
$list->setOffset(0);
}
//save to session
$name = (isset($request->list) ? $request->list : 'instances');
$listHelper->updateList($name, $list, true);
// avoid setting up twice
$this->_isSetup = true;
// redirect normal requests if config-params are given to a param-free uri
// (so a browser reload by user does nothing unwanted)
if (!$request->isXmlHttpRequest()) {
//strip of url parameters that modify the list
$url = new OntoWiki_Url(
array(),
null,
array('init', 'instancesconfig', 's', 'p', 'limit', 'class', 'list')
);
//redirect
$redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
$redirector->gotoUrl($url);
}
}
}
}
================================================
FILE: application/classes/OntoWiki/Controller/Plugin/SetupHelper.php
================================================
*/
class OntoWiki_Controller_Plugin_SetupHelper extends Zend_Controller_Plugin_Abstract
{
/**
* Denotes whether the setup has been performed
*
* @var boolean
*/
protected $_isSetup = false;
/**
* RouteStartup is triggered before any routing happens.
*/
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
/**
* @trigger onRouteStartup
*/
$event = new Erfurt_Event('onRouteStartup');
$event->trigger();
}
/**
* RouteShutdown is the earliest event in the dispatch cycle, where a
* fully routed request object is available
*/
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
// only once
if (!$this->_isSetup) {
$frontController = Zend_Controller_Front::getInstance();
$ontoWiki = OntoWiki::getInstance();
// instantiate model if parameter passed
if (isset($request->m)) {
$store = $ontoWiki->erfurt->getStore();
try {
$model = $store->getModel($request->getParam('m', null, false));
$ontoWiki->selectedModel = $model;
} catch (Erfurt_Store_Exception $e) {
// When no user is given (Anoymous) give the requesting party a chance to authenticate.
if (Erfurt_App::getInstance()->getAuth()->getIdentity()->isAnonymousUser()) {
// In this case we allow the requesting party to authorize...
$response = $frontController->getResponse();
$response->setException(new OntoWiki_Http_Exception(401));
return;
}
// post error message
$ontoWiki->prependMessage(
new OntoWiki_Message(
'
Could not instantiate model: ' . $e->getMessage() . '
' .
'Return to index page',
OntoWiki_Message::ERROR, array('escape' => false)
)
);
// hard redirect since finishing the dispatch cycle will lead to errors
header('Location:' . $ontoWiki->config->urlBase . 'error/error');
return;
}
}
// instantiate resource if parameter passed
if (isset($request->r)) {
$store = $ontoWiki->erfurt->getStore();
$rParam = $request->getParam('r', null, true);
$graph = $ontoWiki->selectedModel;
if (null === $graph) {
// try to use first readable graph
$possibleGraphs = $store->getGraphsUsingResource((string)$rParam, true);
if (count($possibleGraphs) > 0) {
try {
$graph = $store->getModel($possibleGraphs[0]);
$ontoWiki->selectedModel = $graph;
} catch (Erfurt_Store_Exception $e) {
$graph = null;
// fail as before (see below)
}
}
}
if ($graph instanceof Erfurt_Rdf_Model) {
$resource = new OntoWiki_Resource($rParam, $graph);
$ontoWiki->selectedResource = $resource;
} else {
// post error message
$ontoWiki->prependMessage(
new OntoWiki_Message(
'
Could not instantiate resource. No model selected.
' .
'Return to index page',
OntoWiki_Message::ERROR, array('escape' => false)
)
);
// hard redirect since finishing the dispatch cycle will lead to errors
header('Location:' . $ontoWiki->config->urlBase . 'error/error');
return;
}
}
/**
* @trigger onRouteShutdown
*/
$event = new Erfurt_Event('onRouteShutdown');
$event->request = $request;
$event->trigger();
// avoid setting up twice
$this->_isSetup = true;
}
}
}
================================================
FILE: application/classes/OntoWiki/Dispatcher.php
================================================
*/
class OntoWiki_Dispatcher extends Zend_Controller_Dispatcher_Standard
{
/**
* The extension manager
*
* @var OntoWiki_Extension_Manager
*/
protected $_extensionManager = null;
/**
* Base for building URLs
*
* @var string
*/
protected $_urlBase = '';
public function __construct($params = array())
{
if (array_key_exists('url_base', $params)) {
$urlBase = (string)$params['url_base'];
unset($params['url_base']);
}
parent::__construct($params);
$this->urlBase = $urlBase;
}
/**
* Sets the component manager
*/
public function setExtensionManager(OntoWiki_Extension_Manager $extensionManager)
{
$this->_extensionManager = $extensionManager;
}
/**
* Gets the component manager
*/
public function getExtensionManager()
{
return $this->_extensionManager;
}
/**
* Get controller class name
*
* Try request first; if not found, try pulling from request parameter;
* if still not found, fallback to default
*
* @param Zend_Controller_Request_Abstract $request
*
* @return string|false Returns class name on success
*/
public function getControllerClass(Zend_Controller_Request_Abstract $request)
{
$controllerName = $request->getControllerName();
if (empty($controllerName)) {
if (!$this->getParam('useDefaultControllerAlways')) {
return false;
}
$controllerName = $this->getDefaultControllerName();
$request->setControllerName($controllerName);
}
// Zend 1.10+ changes
$className = $this->formatControllerName($controllerName);
$controllerDirs = $this->getControllerDirectory();
$module = $request->getModuleName();
if ($this->isValidModule($module)) {
$this->_curModule = $module;
$this->_curDirectory = $controllerDirs[$module];
} elseif ($this->isValidModule($this->_defaultModule)) {
$request->setModuleName($this->_defaultModule);
$this->_curModule = $this->_defaultModule;
$this->_curDirectory = $controllerDirs[$this->_defaultModule];
} else {
require_once 'Zend/Controller/Exception.php';
throw new Zend_Controller_Exception('No default module defined for this application');
}
// PATCH
// if component manager has controller registered
// redirect to specific controller dir index
if (null !== $this->_extensionManager) {
if ($this->_extensionManager->isComponentRegistered($controllerName)) {
$dir = $this->_extensionManager->getComponentPrefix() . $controllerName;
$this->_curDirectory = $controllerDirs[$dir];
}
}
return $className;
}
/**
* Returns TRUE if the Zend_Controller_Request_Abstract object can be
* dispatched to a controller.
*
* Use this method wisely. By default, the dispatcher will fall back to the
* default controller (either in the module specified or the global default)
* if a given controller does not exist. This method returning false does
* not necessarily indicate the dispatcher will not still dispatch the call.
*
* @param Zend_Controller_Request_Abstract $action
*
* @return boolean
*/
public function isDispatchable(Zend_Controller_Request_Abstract $request)
{
// Zend 1.10+ changes
$className = $this->getControllerClass($request);
$actionMethod = strtolower($request->getActionName()) . 'Action';
if (class_exists($className, false)) {
if (method_exists($className, $actionMethod)) {
return true;
}
}
$fileSpec = $this->classToFilename($className);
$dispatchDir = $this->getDispatchDirectory();
$test = $dispatchDir . DIRECTORY_SEPARATOR . $fileSpec;
if (Zend_Loader::isReadable($test)) {
require_once $test;
if (method_exists($className, $actionMethod)) {
return true;
}
}
/**
* @trigger onIsDispatchable
* Triggered if no suitable controller has been found. Plug-ins can
* attach to this event in order to modify request URLs or provide
* mechanisms that do not allow a controller/action mapping from URL
* parts.
*/
$pathInfo = ltrim($request->getPathInfo(), '/');
// URI may not contain a whitespace character!
$pathInfo = str_replace(' ', '+', $pathInfo);
$pathInfo = urldecode($pathInfo);
if (class_exists($className, false)) {
// give a chance to let class handle (e.g. index controller news action default)
return true;
}
$event = new Erfurt_Event('onIsDispatchable');
$event->uri = $this->urlBase . $pathInfo;
$event->request = $request;
$eventResult = (bool)$event->trigger();
return $eventResult;
}
}
================================================
FILE: application/classes/OntoWiki/Exception.php
================================================
*/
class OntoWiki_Exception extends Exception
{
}
================================================
FILE: application/classes/OntoWiki/Extension/Manager.php
================================================
*/
class OntoWiki_Extension_Manager
{
const EXTENSION_DEFAULT_DOAP_FILE = 'doap.n3';
const COMPONENT_HELPER_SUFFIX = 'Helper';
const COMPONENT_HELPER_FILE_SUFFIX = 'Helper.php';
const COMPONENT_CLASS_POSTFIX = 'Controller';
const COMPONENT_FILE_POSTFIX = 'Controller.php';
const PLUGIN_CLASS_POSTFIX = 'Plugin';
const PLUGIN_FILE_POSTFIX = 'Plugin.php';
const WRAPPER_CLASS_POSTFIX = 'Wrapper';
const WRAPPER_FILE_POSTFIX = 'Wrapper.php';
const EVENT_NS = 'http://ns.ontowiki.net/SysOnt/Events/';
/**
* Array (extension name -> config)
*
* @var array
*/
protected $_extensionRegistry = array();
/**
* The path scanned for components
*
* @var string
*/
protected $_extensionPath = null;
/**
* The translation object.
*
* @var Zend_Translate
*/
protected $_translate = null;
/**
* Base URL for hyperlinks.
*
* @var string
*/
protected $_componentUrlBase = '';
/**
* Component helpers to be initialized
*
* @var array
*/
protected $_helpers = array();
/**
* stores extensions configs
*
* @var array
*/
protected $_componentRegistry = array();
/**
*
* @var OntoWiki_Module_Registry
*/
protected $_moduleRegistry = null;
//plugins and wrappers are handled by erfurt
/**
* Denotes whether component helpers have been called.
*
* @var boolean
*/
protected $_helpersCalled = false;
/**
* Prefix to distinguish component controller directories
* from other controller directories.
*
* @var string
*/
private $_componentPrefix = '_component_';
/**
* Keys in the component configuration file storing path names that
* should be normalized.
*
* @var array
*/
private $_pathKeys
= array(
'templates',
'languages',
'helpers'
);
/**
* Name of the private section in the component config file
*
* @var string
*/
private $_privateSection = 'private';
/**
* a reference to the erfurt event dispatcher
*
* @var Erfurt_Event_Dispatcher
*/
protected $_eventDispatcher = null;
/**
* folders in the extensions directory that are not extensions
*
* @var array
*/
public $reservedNames = array('themes', 'translations');
/**
* Constructor
*/
public function __construct($extensionPath)
{
if (!(substr($extensionPath, -1) == DIRECTORY_SEPARATOR)) {
$extensionPath .= DIRECTORY_SEPARATOR;
}
$this->_extensionPath = $extensionPath;
OntoWiki_Module_Registry::reset();
//OntoWiki_Module_Registry::getInstance()->resetInstance();
$this->_moduleRegistry = OntoWiki_Module_Registry::getInstance();
$this->_moduleRegistry->setExtensionPath($extensionPath);
//TODO nessesary?
Erfurt_Wrapper_Registry::reset();
$this->_eventDispatcher = Erfurt_Event_Dispatcher::getInstance();
// scan for extensions
$this->_scanExtensionPath();
// scan for translations
$this->_scanTranslations();
// register for event
$dispatcher = Erfurt_Event_Dispatcher::getInstance();
$dispatcher->register('onRouteShutdown', $this);
}
// ------------------------------------------------------------------------
// --- Public Methods -----------------------------------------------------
// ------------------------------------------------------------------------
/**
* Returns component.
*
* @return array
*/
public function getExtensionConfig($name)
{
if (isset($this->_extensionRegistry[$name])) {
return $this->_extensionRegistry[$name];
}
}
/**
* Returns registered extensions.
*
* @return array
*/
public function getExtensions()
{
return $this->_extensionRegistry;
}
/**
* Returns registered components.
*
* @return array
*/
public function getComponents()
{
return $this->_componentRegistry;
}
/**
* Returns the helper associated with the component specified.
*
* @throws OntoWiki_Component_Exception if no component with the specified name has been registered or
* OntoWiki_Component_Exception if the specified component has no helper defined.
* @return OntoWiki_Component_Helper
*/
public function getComponentHelper($componentName)
{
if (!$this->isExtensionRegistered($componentName)) {
throw new OntoWiki_Component_Exception('Component with key "' . $componentName . '" not registered');
}
if (!isset($this->_helpers[$componentName]['instance'])) {
throw new OntoWiki_Component_Exception('no helper loaded for component "' . $componentName . '"');
}
return $this->_helpers[$componentName]['instance'];
}
/**
* Returns the path the component manager used to search for components
* because there is one component per extension, this path is equal to the extension path.
*
* @return string
*/
public function getComponentPath()
{
return $this->getExtensionPath();
}
/**
* Returns the path the extension manager used to search for extensions.
*
* @return string
*/
public function getExtensionPath($name = null)
{
if ($name == null) {
return $this->_extensionPath;
} else {
return $this->_extensionPath . $name;
}
}
/**
* Returns the specified component's URL.
*
* @throws OntoWiki_Component_Exception if no component with the specified name has been registered
* @return string
*/
public function getComponentUrl($componentName)
{
if (!$this->isExtensionRegistered($componentName)) {
throw new OntoWiki_Component_Exception("Component with key '$componentName' not registered");
}
return $this->_componentUrlBase . $componentName . '/';
}
/**
* Checks whether a specific extension is registered.
*
*
* @param string $componentName
*
* @return boolean
*/
public function isExtensionRegistered($exName)
{
return isset($this->_extensionRegistry[$exName]);
}
/**
* Checks whether a specific component is registered.
*
* @deprecated
*
* @param string $componentName
*
* @return boolean
*/
public function isComponentRegistered($componentName)
{
return array_key_exists($componentName, $this->_componentRegistry);
}
/**
* Checks whether a specific component is activated
* in its configuration file.
*
* @param string $componentName
*
* @return boolean
*/
public function isExtensionActive($componentName)
{
return array_key_exists($componentName, $this->_extensionRegistry)
&& $this->_extensionRegistry[$componentName]->enabled;
}
/**
* Returns a prefix that can be used to distinguish components from
* other extensions, i.e. modules or plugins.
*
* @deprecated
*
* @return string
*/
public function getComponentPrefix()
{
return $this->_componentPrefix;
}
/**
* Returns the helper path for a given component.
*
* @param string $componentName
*
* @return string
*/
public function getComponentHelperPath($componentName)
{
if (!$this->isExtensionRegistered($componentName)) {
throw new OntoWiki_Component_Exception("Component with key '$componentName' not registered");
}
if (isset($this->_extensionRegistry[$componentName]->helpers)) {
$path = $this->_extensionPath
. $componentName
. DIRECTORY_SEPARATOR
. $this->_extensionRegistry[$componentName]->helpers;
return $path;
}
}
/**
* Returns the template path for a given component.
*
* @param string $componentName
*
* @return string
*/
public function getComponentTemplatePath($componentName)
{
if (!$this->isExtensionRegistered($componentName)) {
throw new OntoWiki_Component_Exception("Component with key '$componentName' not registered");
}
if (isset($this->_extensionRegistry[$componentName]->templates)) {
$path = $this->_extensionPath
. $componentName
. DIRECTORY_SEPARATOR
. $this->_extensionRegistry[$componentName]->templates;
return $path;
}
return $this->_extensionPath
. $componentName
. DIRECTORY_SEPARATOR;
}
/**
* Returns the component's private configuration section
*
* @param string $extensionName
*
* @return array|null
*/
public function getPrivateConfig($extensionName)
{
if (!$this->isExtensionRegistered($extensionName)) {
throw new OntoWiki_Component_Exception("Component with key '$extensionName' not registered");
}
return $this->_extensionRegistry[$extensionName]->{$this->_privateSection};
}
/**
* Sets the base URL for hyperlinks.
*
* @param string $urlBase
*/
public function setComponentUrlBase($componentUrlBase)
{
$componentUrlBase = (string)$componentUrlBase;
$this->_componentUrlBase = trim($componentUrlBase, '/\\') . '/';
return $this;
}
/**
* Sets the translation object to be used for string translation.
*
* @param Zend_Translate $translate
*/
public function setTranslate(Zend_Translate $translate)
{
$this->_translate = $translate;
// (re)scan for translations
$this->_scanTranslations();
return $this;
}
/**
* Event Handler, called by event dispatcher after controller and action is determined
* initializes the component helpers, so they can react
*
* @param Erfurt_Event $event
*/
public function onRouteShutdown(Erfurt_Event $event)
{
// init component helpers
if (!$this->_helpersCalled) {
foreach ($this->_helpers as $componentName => &$helper) {
// only if helper has not been previously loaded
if (!isset($helper['instance'])) {
$helperInstance = $this->_loadHelper($componentName, $this->getExtensionConfig($componentName));
} else {
$helperInstance = $this->_helpers[$componentName]['instance'];
}
$helperInstance->init();
}
$this->_helpersCalled = true;
}
}
/**
* load helpers for a component
*
* @param $componentName
* @param $config
*
* @return mixed
* @throws OntoWiki_Component_Exception
*/
protected function _loadHelper($componentName, $config)
{
if (!isset($this->_helpers[$componentName])) {
throw new OntoWiki_Component_Exception("No helper defined for component '$componentName'.");
}
$helperSpec = $this->_helpers[$componentName];
// load helper class
require_once $helperSpec['path'];
if (class_exists($helperSpec['class'])) {
// instantiate helper object
$helperInstance = new $helperSpec['class']($config);
} else {
throw new OntoWiki_Component_Exception(
"required helper class '" . $helperSpec['class'] .
"' could not be found for component '$componentName'."
);
}
// register helper events
if (isset($helperSpec['events'])) {
$dispatcher = Erfurt_Event_Dispatcher::getInstance();
foreach ($helperSpec['events'] as $currentEvent) {
if (substr($currentEvent, 0, strlen(self::EVENT_NS)) == self::EVENT_NS) {
//currently we only accept events from the ontowiki event namespace
$currentEvent = substr($currentEvent, strlen(self::EVENT_NS));
}
$dispatcher->register($currentEvent, $helperInstance);
}
}
$this->_helpers[$componentName]['instance'] = $helperInstance;
return $helperInstance;
}
/**
* scan the extension folder for configs modified after $time
* the default doap file could have been touched OR the local ini
* return an array(string->int) where the key is the extension name and the value is
* 0 - local ini modified after $time
* 1 - default doap file modified after $time
* 2 - both modified after $time
*
* @param $time int unix timestamp
*
* @return array
*/
private function _getModifiedConfigsSince($time)
{
$dir = new DirectoryIterator($this->_extensionPath);
$mod = array();
foreach ($dir as $file) {
if (!$file->isDot() && $file->isDir() && !in_array($file->getFileName(), $this->reservedNames)) {
//for all folders in /extensions/
$extensionName = $file->getFileName();
$modifiedLocalConfig = @filemtime($this->_extensionPath . $extensionName . '.ini');
if ($modifiedLocalConfig && $modifiedLocalConfig > $time) { //check for modification on the local config
$mod[$extensionName] = 0;
}
$modifiedDefaultConfig = @filemtime(
$file->getRealPath() . DIRECTORY_SEPARATOR . self::EXTENSION_DEFAULT_DOAP_FILE
);
if ($modifiedDefaultConfig && $modifiedDefaultConfig > $time) { //and the default config
if (isset($mod[$extensionName])) {
$mod[$extensionName] = 2;
} else {
$mod[$extensionName] = 1;
}
}
}
}
return $mod;
}
/**
* get the location of the cache
*
* @return string
* @deprecated use Ontowiki::getCache to access cache
* @todo to be deleted in next version
*/
public function getCachePath()
{
throw new BadMethodCallException(
'Method OntoWiki_Extension_Manager::getCachePath is deprecated. Please use Ontowiki cache'
);
}
/**
* invalidate the cache
*/
public function clearCache()
{
$cache = OntoWiki::getInstance()->getCache();
$cache->clean(Zend_Cache::CLEANING_MODE_ALL);
}
/**
* Scans the component path for conforming components and
* announces their paths to appropriate components.
*/
private function _scanExtensionPath()
{
$cache = OntoWiki::getInstance()->getCache();
if (!($config = $cache->load('ow_extensionConfig'))) {
$config = array();
$dir = new DirectoryIterator($this->_extensionPath);
foreach ($dir as $file) {
if (!$file->isDot() && $file->isDir()) {
if (!in_array($file->getFileName(), $this->reservedNames)) {
$extensionName = $file->getFileName();
$currentExtensionPath = $file->getPathname() . DIRECTORY_SEPARATOR;
// parse all extensions on the filesystem
if (is_readable($currentExtensionPath . self::EXTENSION_DEFAULT_DOAP_FILE)) {
$config[$extensionName] = $this->_loadConfigs($extensionName);
}
}
}
}
$cache->save(array_reverse($config));
}
$view = OntoWiki::getInstance()->view;
//register the discovered extensions within ontowiki
foreach ($config as $extensionName => $extensionConfig) {
$currentExtensionPath = $this->_extensionPath . $extensionName . DIRECTORY_SEPARATOR;
if (!$extensionConfig->enabled) {
continue;
}
//templates can be in the main extension folder
$view->addScriptPath($currentExtensionPath);
if (isset($extensionConfig->templates)) {
//or in a folder specified in config
$view->addScriptPath($currentExtensionPath . $extensionConfig->templates);
}
//check for other helpers
if (isset($extensionConfig->helpers)) {
$view->addHelperPath(
$currentExtensionPath . $extensionConfig->helpers,
ucfirst($extensionName) . '_View_Helper_'
);
}
//check for component class (only one per extension for now)
if (file_exists($currentExtensionPath . ucfirst($extensionName) . self::COMPONENT_FILE_POSTFIX)) {
$this->_addComponent($extensionName, $currentExtensionPath, $extensionConfig);
}
//check for modules and plugins (multiple possible)
//TODO declare them in the config?
if (is_dir($currentExtensionPath)) {
$extensionDir = new DirectoryIterator($currentExtensionPath);
foreach ($extensionDir as $extensionDirFile) {
$filename = $extensionDirFile->getFilename();
$subStr = substr($filename, -strlen(OntoWiki_Module_Registry::MODULE_FILE_POSTFIX));
if ($subStr === OntoWiki_Module_Registry::MODULE_FILE_POSTFIX) {
$this->_addModule($extensionName, $filename, $currentExtensionPath, $extensionConfig);
} else {
$subStrB = substr($filename, -strlen(self::PLUGIN_FILE_POSTFIX));
if ($subStrB === self::PLUGIN_FILE_POSTFIX) {
$this->_addPlugin($filename, $currentExtensionPath, $extensionConfig);
} else {
$subStrC = substr($filename, -strlen(self::WRAPPER_FILE_POSTFIX));
if ($subStrC === self::WRAPPER_FILE_POSTFIX) {
$this->_addWrapper($filename, $currentExtensionPath, $extensionConfig);
}
}
}
}
}
}
//save to instance
$this->_extensionRegistry = $config;
}
/**
* adds a component to the internal registry.
*
* @param string $componentName the component's (folder) name
* @param string $componentPath the path to the component folder
* @param array $config the config of the components extension
*/
private function _addComponent($componentName, $componentPath, $config)
{
// load helper
$helperClassName = ucfirst($componentName) . self::COMPONENT_HELPER_SUFFIX;
$helperPathName = $componentPath . ucfirst($componentName) . self::COMPONENT_HELPER_FILE_SUFFIX;
if (is_readable($helperPathName)) {
$helperSpec = array(
'path' => $helperPathName,
'class' => $helperClassName
);
// store events
$events = array();
if (isset($config->helperEvents)) {
$events = $config->helperEvents;
} else {
if (isset($config->helperEvent)) {
$events = $config->helperEvent;
}
}
if ($events instanceof Zend_Config) {
$events = $events->toArray();
} else {
if (!is_array($events)) {
$events = array($events);
}
}
$helperSpec['events'] = $events;
if ($config->enabled) {
$this->_helpers[$componentName] = $helperSpec;
// event helpers need to be called early
if (!empty($helperSpec['events'])) {
$this->_loadHelper($componentName, $config);
}
//helpers without events will be instantiated onRouteShutdown
}
}
$action = isset($config->action) ? $config->action : null;
$position = isset($config->position) ? $config->position : null;
if (isset($config->navigation) && (boolean)$config->navigation && $config->enabled) {
// register with navigation
OntoWiki::getInstance()->getNavigation()->register(
$componentName,
array(
'controller' => $componentName,
'action' => $action,
'name' => $config->name,
'priority' => $position,
'active' => false
)
);
}
$this->_componentRegistry[$componentName] = $config;
}
/**
*
* @param $extensionName
* @param $moduleFilename
* @param $modulePath
* @param null $config
*/
protected function _addModule($extensionName, $moduleFilename, $modulePath, $config = null)
{
//one extension can contain many modules - so they share a config file
//but each module needs different settings
//so we got this trickery to enables per-module-config
//everything within the config key "config->module->$modulename" will be made toplevel config
if (isset($config->modules)) {
$moduleName = strtolower(
substr(
$moduleFilename,
0,
strlen($moduleFilename) - strlen(OntoWiki_Module_Registry::MODULE_FILE_POSTFIX)
)
);
if (isset($config->modules->{$moduleName})) {
//dont touch the original config (seen also by components etc)
$config = unserialize(serialize($config));
$config->merge($config->modules->{$moduleName}); //pull this config up!
}
}
//read context(s)
if (isset($config->context) && is_string($config->context)) {
$contexts = array($config->context);
} else {
if (isset($config->context) && is_object($config->context)) {
$contexts = $config->context->toArray();
} else {
if (isset($config->contexts) && is_object($config->contexts)) {
$contexts = $config->contexts->toArray();
} else {
$contexts = array(OntoWiki_Module_Registry::DEFAULT_CONTEXT);
}
}
}
// register for context(s)
foreach ($contexts as $context) {
$this->_moduleRegistry->register($extensionName, $moduleFilename, $context, $config);
}
}
/**
* adds a wrapper
*
* @param string $filename
* @param string $wrapperPath
*/
protected function _addWrapper($filename, $wrapperPath, $config)
{
$owApp = OntoWiki::getInstance();
$wrapperManager = new Erfurt_Wrapper_Manager();
$wrapperManager->addWrapperExternally(
strtolower(substr($filename, 0, strlen($filename) - strlen(self::WRAPPER_FILE_POSTFIX))),
$wrapperPath,
isset($config->private) ? $config->private : new Zend_Config(array(), true)
);
}
/**
* Adds a plugin and registers it with the dispatcher.
*
* @param string $filename
* @param string $pluginPath
*/
private function _addPlugin($filename, $pluginPath, $config)
{
$owApp = OntoWiki::getInstance();
$pluginManager = $owApp->erfurt->getPluginManager(false);
$pluginManager->addPluginExternally(
strtolower(
substr(
$filename,
0,
strlen($filename) - strlen(self::PLUGIN_FILE_POSTFIX)
)
),
$filename,
$pluginPath,
$config
);
}
private static $_owconfigNS = 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/';
/**
* interpret a doap triple-set to a config array
*
* @static
*
* @param $triples
* @param $name string name of the extension
* @param $base string base URI from parsing
* @param $path string path of the original file (just for error reporting)
*
* @return array
* @throws Exception
*/
public static function triples2configArray($triples, $name, $base, $path)
{
$memModel = new Erfurt_Rdf_MemoryModel($triples);
$owconfigNS = self::$_owconfigNS;
$doapNS = 'http://usefulinc.com/ns/doap#';
$mapping = array(
$owconfigNS . 'enabled' => 'enabled',
$owconfigNS . 'helperEvent' => 'helperEvents',
$owconfigNS . 'templates' => 'templates',
$owconfigNS . 'helpers' => 'helpers',
$owconfigNS . 'languages' => 'languages',
$owconfigNS . 'defaultAction' => 'action',
$owconfigNS . 'class' => 'classes',
$doapNS . 'name' => 'name',
$doapNS . 'description' => 'description',
$doapNS . 'maintainer' => 'authorUrl',
$owconfigNS . 'authorLabel' => 'author',
EF_RDFS_LABEL => 'title'
);
$scp = $owconfigNS . 'config'; //sub config property
$mp = $owconfigNS . 'hasModule'; //module property
$extensionUri = $memModel->getValue($base, 'http://xmlns.com/foaf/0.1/primaryTopic');
if ($extensionUri == null) {
throw new Exception(
'DOAP config for extension ' . $name .
': missing triple (@base, foaf:primaryTopic, ). ' .
'Base was: "' . $base . '". In doap file: "' . $path . '".'
);
}
$privateNS = $memModel->getValue($extensionUri, $owconfigNS . 'privateNamespace');
$modules = array();
$config = array('default' => array(), 'private' => array(), 'events' => array(), 'modules' => array());
$subconfigs = array();
foreach ($memModel->getPO($extensionUri) as $key => $values) {
//handle subconfigs
if ($key == $scp) {
foreach ($values as $val) {
$subconfigs[] = $val['value'];
}
continue;
} else {
if ($key == $mp) {
//handle modules
foreach ($values as $val) {
$modules[] = $val['value'];
}
continue;
} else {
if ($key == $owconfigNS . 'pluginEvent') {
//handle events that belong to plugins
foreach ($values as $value) {
$config['events'][] = $value['value'];
}
continue;
} else {
if (isset($mapping[$key])) {
$mappedKey = $mapping[$key];
$section = 'default';
} else {
$mappedKey = self::getPrivateKey($key, $privateNS);
if ($mappedKey == null) {
continue; //skip irregular keys
}
$section = 'private';
}
}
}
}
foreach ($values as $value) {
$value = self::getValue($value, $memModel);
self::addValue($mappedKey, $value, $config[$section]);
}
}
foreach ($subconfigs as $bnUri) {
$config['private'] = array_merge(
$config['private'],
self::getSubConfig($memModel, $bnUri, $privateNS, $mapping)
);
}
foreach ($modules as $moduleUri) {
$name = strtolower(self::getPrivateKey($moduleUri, $privateNS));
$config['modules'][$name] = array();
foreach ($memModel->getPO($moduleUri) as $key => $values) {
$mappedKey = self::getPrivateKey($key, $owconfigNS);
if ($mappedKey == null) {
continue; //modules can only have specific properties
}
foreach ($values as $value) {
$value = self::getValue($value, $memModel);
self::addValue($mappedKey, $value, $config['modules'][$name]);
}
}
}
if (empty($config['events'])) {
unset($config['events']);
}
//pull up the default module
if (isset($config['modules']['default'])) {
$config = array_merge($config, $config['modules']['default']);
unset($config['modules']['default']);
}
//pull up the default section
$config = array_merge($config, $config['default']);
unset($config['default']);
return $config;
}
/**
* load the doap.n3 file of a extension and transform it into a config array
*
* @param string $path
* @param string $name
*
* @return array config array
*/
public static function loadDoapN3($path, $name)
{
$parser = Erfurt_Syntax_RdfParser::rdfParserWithFormat('n3');
$triples = $parser->parse($path, Erfurt_Syntax_RdfParser::LOCATOR_FILE);
$base = $parser->getBaseUri();
$a = self::triples2configArray($triples, $name, $base, $path);
return $a;
}
/**
* convert a php-rdf value to a php value
* respects booleans especially (literals and URIs are trivial)
*
* @static
*
* @param $value
*
* @return bool
*/
private static function getValue($value, Erfurt_Rdf_MemoryModel $memModel = null)
{
if ($value['type'] == 'literal'
&& isset($value['datatype'])
&& $value['datatype'] == 'http://www.w3.org/2001/XMLSchema#boolean'
) {
$value = $value['value'] == 'true';
} else {
if ($memModel !== null && ($value['type'] == 'uri' || $value['type'] == 'bnode')) {
// Handle collections and containers (rdf:Bag, rdf:Seq) not rdf:Alt because of a bug
$type = $memModel->getValue($value['value'], EF_RDF_NS . 'type');
if ($type == EF_RDF_NS . 'Bag' || $type == EF_RDF_NS . 'Seq') {
// This is a container, convert it to an array
$properties = $memModel->getPO($value['value']);
$value = array();
foreach ($properties as $property => $entry) {
if (strstr($property, EF_RDF_NS . '_')) {
$value[] = $entry[0]['value'];
}
}
} else {
if ($type == EF_RDF_NS . 'nil') {
$value = array();
} else {
$first = $memModel->getValue($value['value'], EF_RDF_NS . 'first');
$rest = $memModel->getValue($value['value'], EF_RDF_NS . 'rest');
if (count($first) > 0 && count($rest) > 0) {
// This is a collection, convert it to an array
$value = array($first);
while ($rest != EF_RDF_NS . 'nil') {
$value[] = $memModel->getValue($rest, EF_RDF_NS . 'first');
$rest = $memModel->getValue($rest, EF_RDF_NS . 'rest');
}
} else {
// unknown Resource
$value = $value['value'];
}
}
}
} else {
$value = $value['value'];
}
}
return $value;
}
/**
* add an value to an array using a key
* if the key is already used, cast it to array and add to that array
*
* @static
*
* @param $key string
* @param $value mixed
* @param $to array
*/
private static function addValue($key, $value, &$to)
{
if (!isset($to[$key])) { //first entry for that key
$to[$key] = $value;
} else {
if (is_array($to[$key])) { //there are already multiple values for that key
if (is_array($value)) {
$to[$key] = array_merge($value, $to[$key]);
} else {
$to[$key][] = $value;
}
} else { //it the second entry for that key, turn to array
if (is_array($value)) {
$to[$key] = array_merge(array($to[$key]), $value);
} else {
$to[$key] = array($to[$key], $value);
}
}
}
}
/**
* clean a config property URI to obtain a config array key
*
* @static
*
* @param $key string
* @param $privateNS string
* @param array $mapping
*
* @return mixed
*/
private static function getPrivateKey($key, $privateNS, $mapping = array())
{
if (isset($mapping[$key])) {
return $mapping[$key];
}
if (strpos($key, $privateNS) === 0) {
//strip private NS, only keep last part
$newKey = substr($key, strlen($privateNS));
} else {
//return only local part
//take the right most / or #
$slashPos = strrpos($key, '/');
$hashPos = strrpos($key, '#');
if ($slashPos < $hashPos) {
$l = $hashPos;
} else {
$l = $slashPos;
}
if ($l == false) {
$newKey = $key; //no / or #
} else {
$newKey = substr($key, $l + 1);
}
}
return preg_replace('[^A-Za-z0-9-_]', '', $newKey); //strip bad chars
}
/**
* read a private config part from a doap Erfurt_Rdf_MemoryModel (recursive)
*
* @static
*
* @param $memModel
* @param $bnUri
* @param $privateNS
* @param $mapping
*
* @return array
*/
private static function getSubConfig(Erfurt_Rdf_MemoryModel $memModel, $bnUri, $privateNS, $mapping)
{
$kv = array();
$name = $memModel->getValue($bnUri, self::$_owconfigNS . 'id');
if ($name == null) {
return array();
}
foreach ($memModel->getPO($bnUri) as $key => $values) {
if ($key == EF_RDF_TYPE || $key == self::$_owconfigNS . 'id') {
continue;
}
if ($key == self::$_owconfigNS . 'config') {
foreach ($values as $value) {
$kv = array_merge($kv, self::getSubConfig($memModel, $value['value'], $privateNS, $mapping));
}
} else {
$mappedKey = self::getPrivateKey($key, $privateNS, $mapping);
foreach ($values as $value) {
$value = self::getValue($value, $memModel);
self::addValue($mappedKey, $value, $kv);
}
}
}
$r = array($name => $kv);
return $r;
}
/**
* load configs for an extension
* - respect local ini's
* - fix missing or dirty values
*
* @param $name string containing the name of an extension
*
* @return Zend_Config
*/
private function _loadConfigs($name)
{
$path = $this->_extensionPath . $name . DIRECTORY_SEPARATOR;
$config = new Zend_Config(self::loadDoapN3($path . self::EXTENSION_DEFAULT_DOAP_FILE, $name), true);
// overwrites default config with local config
$localConfigPath = $this->_extensionPath . $name . '.ini';
if (is_readable($localConfigPath)) {
//the local config is still in ini syntax
$localConfig = new Zend_Config_Ini($localConfigPath, null, true);
$config->merge($localConfig);
}
//fix missing names
if (!isset($config->name)) {
$config->name = $name;
}
//fix deprecated/invalid values for "enabled"
if (is_string($config->enabled)) {
switch ($config->enabled) {
case '1':
case 'enabled':
case 'true':
case 'on':
case 'yes':
$config->enabled = true;
break;
default:
$config->enabled = false;
}
}
// normalize paths
foreach ($this->_pathKeys as $pathKey) {
if (isset($config->{$pathKey})) {
$config->{$pathKey} = rtrim($config->{$pathKey}, '/\\') . '/';
}
}
// save component's path
$config->path = $path;
return $config;
}
/**
* Reads all available component translations and adds them to the translation object
*/
private function _scanTranslations()
{
// check for valid translation object
if (is_object($this->_translate)) {
foreach ($this->_extensionRegistry as $component => $settings) {
// check if component owns translation
if (isset($settings->languages)
&& is_readable($settings->path . $settings->languages)
) {
// keep current locale
$locale = $this->_translate->getAdapter()->getLocale();
$this->_translate->addTranslation(
$settings->path . $settings->languages,
null,
array('scan' => Zend_Translate::LOCALE_FILENAME)
);
// reset current locale
$this->_translate->setLocale($locale);
}
}
}
}
}
================================================
FILE: application/classes/OntoWiki/Http/Exception.php
================================================
*/
class OntoWiki_Http_Exception extends OntoWiki_Exception
{
const ERROR_CODE_BASE = 3000;
protected $_responseCode = 0;
public function __construct($responseCode, $message = null)
{
parent::__construct(
((null !== $message) ? $message : Zend_Http_Response::responseCodeAsText($responseCode)),
self::ERROR_CODE_BASE + (int)$responseCode
);
$this->_responseCode = $responseCode;
}
public function getResponseMessage()
{
return $this->getMessage();
}
public function getResponseCode()
{
return $this->_responseCode;
}
}
================================================
FILE: application/classes/OntoWiki/Jobs/Cron.php
================================================
*/
class OntoWiki_Jobs_Cron extends Erfurt_Worker_Job_Abstract
{
/**
* on which integer the delay countdown starts
*/
const DELAY_COUNTDOWN = 10;
/**
* the maximum time in seconds where a cached chain startTime is not taken
* as too old and a new chain is fired
*/
const DELAY_MERCYSECONDS = 10;
/**
* gives an DateInterval in seconds (for better comparison)
* taken from http://www.php.net/manual/en/dateinterval.format.php#102271
*
* @param DateInterval $interval object to recalculate
*
* @return integer
*/
private function _toSeconds(DateInterval $interval)
{
$y = $interval->y * 365 * 24 * 60 * 60;
$m = $interval->m * 30 * 24 * 60 * 60;
$d = $interval->d * 24 * 60 * 60;
$h = $interval->h * 60 * 60;
$i = $interval->i * 60;
$s = $interval->s;
return $y + $m + $d + $h + $i + $s;
}
/**
* sleeps an amount of time and calls the next job
*
* @param mixed $load the load of the next job
* @param int $inXSeconds time in seconds when the next job is called
*
* @return void
*/
private function _next($load = null, $inXSeconds = 2)
{
if ((int)$inXSeconds > 0) {
sleep((int)$inXSeconds);
}
if ($load == null) {
OntoWiki::getInstance()->callJob('cron');
} else {
OntoWiki::getInstance()->callJob('cron', $load);
}
}
/**
* initializes a new load
*
* @return void
*/
private function _getNewLoad()
{
$this->setValue($this->timeStart, 'timeStart');
$this->setValue($this->timeStart, 'timeLast');
$this->load = array(
'lastMinutly' => $this->nowString,
'lastHourly' => $this->nowString,
'lastDaily' => $this->nowString,
'timeStart' => $this->timeStart,
);
}
/**
* trigger events, based on nowstring and load
*
* @return void
*/
private function _triggerEvents()
{
$now = new DateTime($this->nowString);
$lastMinutly = new DateTime($this->load->lastMinutly);
$lastMinutlyDiff = $this->_toSeconds($now->diff($lastMinutly));
if ($lastMinutlyDiff >= 60) {
$this->load->lastMinutly = $this->nowString;
/**
* @trigger onEveryMinute
*/
$event = new Erfurt_Event('onEveryMinute');
$event->trigger();
if ($event->handled) {
$this->logSuccess('triggered onEveryMinute (handled)');
} else {
$this->logSuccess('triggered onEveryMinute (but not handled)');
}
};
$lastHourly = new DateTime($this->load->lastHourly);
$lastHourlyDiff = $this->_toSeconds($now->diff($lastHourly));
if ($lastHourlyDiff >= 60 * 60) {
$this->load->lastHourly = $this->nowString;
/**
* @trigger onEveryHour
*/
$event = new Erfurt_Event('onEveryHour');
$event->trigger();
if ($event->handled) {
$this->logSuccess('triggered onEveryHour (handled)');
} else {
$this->logSuccess('triggered onEveryHour (but not handled)');
}
};
$lastDaily = new DateTime($this->load->lastDaily);
$lastDailyDiff = $this->_toSeconds($now->diff($lastDaily));
if ($lastDailyDiff >= 60 * 60 * 24) {
$this->load->lastDaily = $this->nowString;
/**
* @trigger onEveryDay
*/
$event = new Erfurt_Event('onEveryDay');
$event->trigger();
if ($event->handled) {
$this->logSuccess('triggered onEveryDay (handled)');
} else {
$this->logSuccess('triggered onEveryDay (but not handled)');
}
};
}
/**
* run the job
*
* @param mixed $load payload object
*
* @return null
*/
public function run($load)
{
// the micro-timestamp to identify the start of the cron chain
$this->timeStart = microtime(true);
// the timestring to calculate the events
$this->nowString = date("Y-m-d H:i:s");
// the timestamp when a continous chain of cron jobs was started
$timeStartValue = $this->getValue('timeStart');
// the timestamp when the last link in the chain was started
$timeLastValue = $this->getValue('timeLast');
if (empty($load)) {
// situation 1: no previous timestamps cached -> init
if ($timeStartValue === false || $timeLastValue === false) {
// first start without payload and cached values,
// so we create a fresh chain
$this->_getNewLoad();
$this->_next($this->load);
} else {
// situation 2: previous timestamps cached -> handle
$timeLastDiff = $this->timeStart - $timeLastValue;
if ($timeLastDiff > self::DELAY_MERCYSECONDS) {
// first start without payload but WITH invalid old cache,
// we can create a fresh chain
$this->logSuccess(
'started without payload,'.
' and OLD cached timestamps exists -- '. $timeLastDiff .
' (init on ' . (string)$this->timeStart . ')'
);
$this->_getNewLoad();
$this->_next($this->load);
} else {
// first start without payload but WITH opposing cache,
// we need to look forward
$this->logFailure(
'started without payload, but cached timestamps exists ' .
' (do nothing for now and try again '.self::DELAY_COUNTDOWN.' times).'
);
$this->_next(array('delayed' => self::DELAY_COUNTDOWN), 1);
}
}
} else { // load exists
if (!empty($load->delayed) && (int)$load->delayed > 0) {
$this->logFailure(
'started delayed: ' . $load->delayed
);
$timeLastDiff = $this->timeStart - $timeLastValue;
if ($timeLastDiff > self::DELAY_MERCYSECONDS) {
// this is a fresh restart since we know, that the chain can
// be created now
$this->_next(null, 0);
} else {
// this is a delayed job which is agains started to re-run the tests
$this->_next(array('delayed' => $load->delayed - 1), 1);
}
} else if (empty($load->timeStart) || (string)$load->timeStart !== (string)$timeStartValue) {
// this is a start with load but it does not belong to the
// cron chain of the cached timeStart
$this->logFailure(
'started with payload, but cached timestamp differs' .
' (do nothing, chain dies).'
);
} else {
// finally, this is a "normal" job which can trigger events and
// which setup a new timeLast
$this->load = $load;
$this->_triggerEvents();
$this->setValue($this->timeStart, 'timeLast');
$this->_next($this->load);
}
}
}
}
================================================
FILE: application/classes/OntoWiki/Menu/Registry.php
================================================
*/
class OntoWiki_Menu_Registry
{
/**
* Menu registry; an array of menu instances
*
* @var array
*/
private $_menus = array();
/**
* Singleton instance
*
* @var OntoWiki_Menu_Registry
*/
private static $_instance = null;
/**
* Singleton instance
*
* @return OntoWiki_Menu_Registry
*/
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Returns the menu denoted by $menuKey.
*
* @param string $menuKey
*
* @return OntoWiki_Menu
*/
public function getMenu($menuKey, $context = null)
{
if (!is_string($menuKey)) {
throw new OntoWiki_Exception('Menu key must be string.');
}
if (!isset($this->_menus[$context])) {
$this->_menus[$context] = array();
}
if (!array_key_exists($menuKey, $this->_menus[$context])) {
$getMethod = '_get' . ucfirst($menuKey) . 'Menu';
if (method_exists($this, $getMethod)) {
$this->setMenu($menuKey, $context, $this->$getMethod($context));
} else {
$this->setMenu($menuKey, $context, new OntoWiki_Menu());
}
}
return $this->_menus[$context][$menuKey];
}
/**
* Stores the menu $menu with key $menuKey in the registry.
*
* @param string $menuKey
* @param OntoWiki_Menu $menu
* @param boolean $replace
*
* @return OntoWiki_Menu_Registry
*/
public function setMenu($menuKey, $context, OntoWiki_Menu $menu, $replace = true)
{
if (!is_string($menuKey)) {
throw new OntoWiki_Exception('Menu key must be string.');
}
if (!isset($this->_menus[$context])) {
$this->_menus[$context] = array();
}
if (!$replace && array_key_exists($menuKey, $this->_menus[$context])) {
throw new OntoWiki_Exception("Menu with key '$menuKey' already registered.");
}
$this->_menus[$context][$menuKey] = $menu;
return $this;
}
private function __construct()
{
$owApp = OntoWiki::getInstance();
$this->setMenu('application', null, $this->_getApplicationMenu());
// check if a resource is selected
if (isset($owApp->selectedResource) && $owApp->selectedResource) {
$resource = (string)$owApp->selectedResource;
$this->setMenu('resource', $resource, $this->_getResourceMenu($resource));
}
}
/**
* Create the application menu and fill it with its default entries
*/
private function _getApplicationMenu($context = null)
{
$owApp = OntoWiki::getInstance();
// user sub menu
if ($owApp->erfurt->isActionAllowed('RegisterNewUser')
&& !(isset($owApp->config->ac)
&& ((boolean)$owApp->config->ac->deactivateRegistration === true))
) {
if (!($owApp->erfurt->getAc() instanceof Erfurt_Ac_None)) {
$userMenu = new OntoWiki_Menu();
$userMenu->setEntry('Register New User', $owApp->config->urlBase . 'application/register');
}
}
if ($owApp->user && !$owApp->user->isAnonymousUser()) {
if (!isset($userMenu)) {
$userMenu = new OntoWiki_Menu();
}
if (!$owApp->user->isDbUser()) {
$userMenu->setEntry('Preferences', $owApp->config->urlBase . 'application/preferences');
}
$userMenu->setEntry('Logout', $owApp->config->urlBase . 'application/logout');
}
// view sub menu
$viewMenu = new OntoWiki_Menu();
// extras sub menu
$extrasMenu = new OntoWiki_Menu();
$extrasMenu->setEntry('News', $owApp->config->urlBase . 'index/news');
// help sub menue
$helpMenu = new OntoWiki_Menu();
if (isset($owApp->config->help->documentation) && (trim($owApp->config->help->documentation) !== '')) {
$helpMenu->setEntry('Documentation', trim($owApp->config->help->documentation));
}
if (isset($owApp->config->help->issues) && (trim($owApp->config->help->issues) !== '')) {
$helpMenu->setEntry('Bug Report', trim($owApp->config->help->issues));
}
if (isset($owApp->config->help->versioninfo) && (trim($owApp->config->help->versioninfo) !== '')) {
$helpMenu->setEntry('Version Info', trim($owApp->config->help->versioninfo));
}
$helpMenu->setEntry('About', $owApp->config->urlBase . 'application/about');
// build menu out of sub menus
$applicationMenu = new OntoWiki_Menu();
if (isset($userMenu)) {
$applicationMenu->setEntry('User', $userMenu);
}
$applicationMenu->setEntry('Extras', $extrasMenu)
->setEntry('Help', $helpMenu);
// add cache entry only if use is allowed to use debug action
if ($owApp->erfurt->isActionAllowed('Debug')) {
$debugMenu = new OntoWiki_Menu();
$debugMenu->setEntry('Clear Module Cache', $owApp->config->urlBase . 'debug/clearmodulecache')
->setEntry('Clear Translation Cache', $owApp->config->urlBase . 'debug/cleartranslationcache')
->setEntry('Clear Object & Query Cache', $owApp->config->urlBase . 'debug/clearquerycache')
->setEntry('Start xdebug Session', $owApp->config->urlBase . '?XDEBUG_SESSION_START=xdebug')
->setEntry('Reset Session', $owApp->config->urlBase . 'debug/destroysession');
$applicationMenu->setEntry('Debug', $debugMenu);
}
return $applicationMenu;
}
/**
* Create the context menu for models/knowledge bases and fill it with its default entries
*/
private function _getModelMenu($model = null)
{
$owApp = OntoWiki::getInstance();
if ($model === null) {
$model = $owApp->selectedModel;
}
$config = $owApp->config;
$modelMenu = new OntoWiki_Menu();
// Select Knowledge Base
$url = new OntoWiki_Url(
array('controller' => 'model', 'action' => 'select'),
array()
);
$url->setParam('m', $model, false);
$modelMenu->appendEntry(
'Select Knowledge Base',
(string)$url
);
// View resource
$url = new OntoWiki_Url(
array('action' => 'view'),
array()
);
$url->setParam('m', $model, false);
$url->setParam('r', $model, true);
$modelMenu->appendEntry(
'View as Resource',
(string)$url
);
// check if model could be edited (prefixes and data)
if ($owApp->erfurt->getAc()->isModelAllowed('edit', $model)) {
// Configure Knowledge Base
$url = new OntoWiki_Url(
array('controller' => 'model', 'action' => 'config'),
array()
);
$url->setParam('m', $model, false);
$modelMenu->appendEntry(
'Configure Knowledge Base',
(string)$url
);
// Add Data to Knowledge Base
$url = new OntoWiki_Url(
array('controller' => 'model', 'action' => 'add'),
array()
);
$url->setParam('m', $model, false);
$modelMenu->appendEntry(
'Add Data to Knowledge Base',
(string)$url
);
}
// Model export
if ($owApp->erfurt->getAc()->isActionAllowed(Erfurt_Ac_Default::ACTION_MODEL_EXPORT)) {
// add entries for supported export formats
foreach (Erfurt_Syntax_RdfSerializer::getSupportedFormats() as $key => $format) {
$url = new OntoWiki_Url(
array('controller' => 'model', 'action' => 'export'),
array()
);
$url->setParam('m', $model, false);
$url->setParam('f', $key);
$modelMenu->appendEntry(
'Export Knowledge Base as ' . $format,
(string)$url
);
}
}
// can user delete models?
if ($owApp->erfurt->getAc()->isModelAllowed('edit', $model)
&& $owApp->erfurt->getAc()->isActionAllowed('ModelManagement')
) {
$url = new OntoWiki_Url(
array('controller' => 'model', 'action' => 'delete'),
array()
);
$url->setParam('model', $model, false);
$modelMenu->appendEntry(
'Delete Knowledge Base',
(string)$url
);
}
// add a seperator
$modelMenu->appendEntry(OntoWiki_Menu::SEPARATOR);
return $modelMenu;
}
/**
* Create the (context) menu for resource and fill it with its default entries
*/
private function _getResourceMenu($resource = null)
{
$owApp = OntoWiki::getInstance();
if ($resource === null) {
$resource = $owApp->selectedResource;
}
$config = $owApp->config;
$resourceMenu = new OntoWiki_Menu();
// Add the class Menu if the current resource is a class
$classMenu = $this->_getClassMenu($resource)->toArray();
foreach ($classMenu as $key => $value) {
$resourceMenu->appendEntry($key, $value);
}
if (count($classMenu) > 0) {
$resourceMenu->appendEntry(OntoWiki_Menu::SEPARATOR);
}
// View resource
$url = new OntoWiki_Url(
array('action' => 'view'),
array()
);
$url->setParam('r', $resource, true);
$resourceMenu->appendEntry(
'View Resource',
(string)$url
);
// Edit entries
if ($owApp->erfurt->getAc()->isModelAllowed('edit', $owApp->selectedModel)) {
// edit resource option
$resourceMenu->appendEntry(
'Edit Resource',
'javascript:editResourceFromURI(\'' . (string)$resource . '\')'
);
// Delete resource option
$url = new OntoWiki_Url(
array('controller' => 'resource', 'action' => 'delete'),
array('r')
);
$url->setParam('r', (string)$resource, false);
$resourceMenu->appendEntry('Delete Resource', (string)$url);
}
$resourceMenu->appendEntry(
'Go to Resource (external)',
(string)$resource
);
$resourceMenu->appendEntry(OntoWiki_Menu::SEPARATOR);
foreach (Erfurt_Syntax_RdfSerializer::getSupportedFormats() as $key => $format) {
$resourceMenu->appendEntry(
'Export Resource as ' . $format,
$config->urlBase . 'resource/export/f/' . $key . '?r=' . urlencode($resource)
);
}
return $resourceMenu;
}
/**
* Create the (context) menu for classes and fill it with its default entries
*/
private function _getClassMenu($resource = null)
{
$owApp = OntoWiki::getInstance();
$classMenu = new OntoWiki_Menu();
$query = Erfurt_Sparql_SimpleQuery::initWithString(
'SELECT *
FROM <' . (string)$owApp->selectedModel . '>
WHERE {
<' . $resource . '> a ?type .
}'
);
$results[] = $owApp->erfurt->getStore()->sparqlQuery($query);
$query = Erfurt_Sparql_SimpleQuery::initWithString(
'SELECT *
FROM <' . (string)$owApp->selectedModel . '>
WHERE {
?inst a <' . $resource . '> .
} LIMIT 2'
);
if (count($owApp->erfurt->getStore()->sparqlQuery($query)) > 0) {
$hasInstances = true;
} else {
$hasInstances = false;
}
$typeArray = array();
foreach ($results[0] as $row) {
$typeArray[] = $row['type'];
}
if (in_array(EF_RDFS_CLASS, $typeArray)
|| in_array(EF_OWL_CLASS, $typeArray)
|| $hasInstances
) {
$url = new OntoWiki_Url(
array('action' => 'list'),
array()
);
$url->setParam('class', $resource, false);
$url->setParam('init', "true", true);
$classMenu->appendEntry(
'List Instances',
(string)$url
);
// add class menu entries
if ($owApp->erfurt->getAc()->isModelAllowed('edit', $owApp->selectedModel)) {
$classMenu->appendEntry(
'Create Instance',
"javascript:createInstanceFromClassURI('$resource');"
);
}
}
return $classMenu;
}
}
================================================
FILE: application/classes/OntoWiki/Menu.php
================================================
*/
class OntoWiki_Menu
{
/**
* Menu entry separator
*/
const SEPARATOR = '_---_';
/**
* Array of menu entries
*
* @var array
*/
private $_entries = array();
/**
* Constructor
*/
public function __construct()
{
}
public function appendEntry($entryKey, $entryContent = null)
{
if (!is_string($entryKey)) {
throw new OntoWiki_Exception('Entry key must be string.');
}
if (($entryKey != self::SEPARATOR)
&& !is_string($entryContent) && !is_array($entryContent)
&& !($entryContent instanceof OntoWiki_Menu)
) {
throw new OntoWiki_Exception(
'Menu content must be an instance of ' . __CLASS__ . ' or string, ' . gettype($entryContent) . ' given.'
);
}
if (array_key_exists($entryKey, $this->_entries)) {
throw new OntoWiki_Exception("An entry with key '$entryKey' already exists.");
}
if ($entryKey == self::SEPARATOR) {
$key = self::SEPARATOR . uniqid();
$this->_entries[$key] = self::SEPARATOR;
} else {
$this->_entries[$entryKey] = $entryContent;
}
return $this;
}
public function prependEntry($entryKey, $entryContent = null)
{
if (!is_string($entryKey)) {
throw new OntoWiki_Exception('Entry key must be string.');
}
if (($entryKey != self::SEPARATOR)
&& !is_string($entryContent)
&& !is_array($entryContent)
&& !($entryContent instanceof OntoWiki_Menu)
) {
throw new OntoWiki_Exception(
'Menu content must be an instance of ' . __CLASS__ . ' or string, ' . gettype($entryContent) . ' given.'
);
}
if (array_key_exists($entryKey, $this->_entries)) {
throw new OntoWiki_Exception("An entry with key '$entryKey' already exists.");
}
if ($entryKey == self::SEPARATOR) {
$key = self::SEPARATOR . uniqid();
$this->_entries = array_merge(array($key => self::SEPARATOR), $this->_entries);
} else {
$this->_entries = array_merge(array($entryKey => $entryContent), $this->_entries);
}
return $this;
}
/**
* Sets a menu entry. Throws an exception if a menu key with
* the same name already exists and
*
* @param string $entryKey
* @param string|array|OntoWiki_Menu $entryContent
* If a string is provided, it is used as the target URL for the menu entry.
* If an array is given, it must have a key 'url', whereas 'class' and 'id'
* are optional and can be used for CSS classes and CSS ids respectively.
* An instance of OntoWiki_Menu means, this entry is a submenu.
* @param boolean replace
*/
public function setEntry($entryKey, $entryContent = null, $replace = true)
{
if (!is_string($entryKey)) {
throw new OntoWiki_Exception('Entry key must be string.');
}
if (($entryKey != self::SEPARATOR)
&& !is_string($entryContent)
&& !is_array($entryContent)
&& !($entryContent instanceof OntoWiki_Menu)
) {
throw new OntoWiki_Exception(
'Menu content must be an instance of ' . __CLASS__ . ' or string, ' . gettype($entryContent) . ' given.'
);
}
if (!$replace && array_key_exists($entryKey, $this->_entries)) {
throw new OntoWiki_Exception("An entry with key '$entryKey' already exists.");
}
if ($entryKey == self::SEPARATOR) {
$key = self::SEPARATOR . uniqid();
$this->_entries[$key] = self::SEPARATOR;
} else {
$this->_entries[$entryKey] = $entryContent;
}
return $this;
}
/**
* Returns a sub menu entry. If the sub menu does not
* exist an empty instance of OntoWiki_Menu is returned
* that represents a new submenu.
*
* @param string $subMenuKey
*
* @return OntoWiki_Menu|null
*/
public function getSubMenu($subMenuKey)
{
if (!array_key_exists($subMenuKey, $this->_entries)) {
$subMenu = new OntoWiki_Menu();
$this->setEntry($subMenuKey, $subMenu);
}
if (!$this->_entries[$subMenuKey] instanceof OntoWiki_Menu) {
throw new OntoWiki_Exception("Entry '$subMenuKey' is not a menu.");
}
return $this->_entries[$subMenuKey];
}
/**
* Removes the entry with key $entryKey from the menu.
*
* @param string $entryKey
*/
public function removeEntry($entryKey)
{
if (array_key_exists($entryKey, $this->_entries)) {
unset($this->_entries[$entryKey]);
}
}
/**
* Returns the menu instance as an array
*
* @param boolean $translate Whether to translate keys
* @param boolean $recursive Whether to recursively array-ize this instance
*
* @return array
*/
public function toArray($translate = false, $recursive = true)
{
if ($translate) {
$translation = OntoWiki::getInstance()->translate;
}
$return = array();
foreach ($this->_entries as $key => $content) {
if ($translate) {
$key = $translation->translate($key);
}
if ($content instanceof self) {
if ($recursive) {
$return[$key] = $content->toArray($translate, $recursive);
} else {
$return[$key] = $content;
}
} else {
$return[$key] = $content;
}
}
return $return;
}
/**
* Returns the menu instance as an HTML list
*
* @return array
*/
public function toHtmlList()
{
// TODO:
}
/**
* Returns the menu instance as a JSON array
*
* @return array
*/
public function toJson($translate = true)
{
return json_encode($this->toArray($translate, true));
}
}
================================================
FILE: application/classes/OntoWiki/Message.php
================================================
*/
class OntoWiki_Message
{
/**
* Message of type succes.
* The last operation was executed successfully.
*/
const SUCCESS = 'success';
/**
* Message of type info.
* A notice to help the user interpret the application state.
*/
const INFO = 'info';
/**
* Message of type warning.
* A notice to inform the user the he might not get the results desired
* due to a non-critical application error or false input.
*/
const WARNING = 'warning';
/**
* Message of type error.
* A notice to inform the user of a critical application error that does
* not allow the application to perform under normal circumstances.
*/
const ERROR = 'error';
/**
* Options array
*
* @var array
*/
protected $_options = null;
/**
* The message's type
*
* @var string
*/
protected $_type = null;
/**
* The message text
*
* @var string
*/
protected $_text = null;
/**
* Constructor
*
* @param string $text
* @param string $type
*/
public function __construct($text, $type = self::INFO, $options = array())
{
$this->_options = array_merge(
array(
'escape' => true,
'translate' => true),
$options
);
$this->_type = $type;
$this->_text = $text;
}
/**
* Returns the type of the message
*
* @return string
*/
public function getType()
{
return $this->_type;
}
/**
* Returns the message's text
*
* @return string
*/
public function getText()
{
$text = $this->_translate($this->_text);
if (strlen($text) > 1000) {
$text = substr($text, 0, 1000) . '...';
}
$text = $this->_options['escape'] ? $this->getView()->escape($text) : $text;
return $text;
}
/**
* Returns the view object.
*
* @return OntoWiki_View
*/
protected function getView()
{
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
if (null === $viewRenderer->view) {
$viewRenderer->initView();
}
$view = clone $viewRenderer->view;
$view->clearVars();
return $view;
}
/**
* Returns the translator.
*
* @return Zend_Translate
*/
protected function getTranslator()
{
return OntoWiki::getInstance()->translate;
}
private function _translate($text)
{
if (($this->_options['translate'] === true) && ($translator = $this->getTranslator()) !== null) {
return $translator->translate($text);
}
return $text;
}
}
================================================
FILE: application/classes/OntoWiki/Model/Exception.php
================================================
*/
class OntoWiki_Model_Exception extends OntoWiki_Exception
{
}
================================================
FILE: application/classes/OntoWiki/Model/Hierarchy.php
================================================
*/
class OntoWiki_Model_Hierarchy extends OntoWiki_Model
{
/**
* Direction of the hierarchy relation is downwards.
*/
const DIRECTION_DOWN = 1;
/**
* Direction of the hierarchy relation is upwards.
*/
const DIRECTION_UP = 2;
/**
* Default hierarchy options
*
* @var array
*/
private $_options
= array(
'object_types' => array(EF_RDFS_CLASS, EF_OWL_CLASS),
'ignore_ns' => array(EF_RDF_NS, EF_RDFS_NS, EF_OWL_NS), // EF_OWL_THING
'sub_relation' => EF_RDFS_SUBCLASSOF,
'sub_direction' => self::DIRECTION_DOWN,
'inst_relation' => EF_RDF_TYPE,
'inst_direction' => self::DIRECTION_DOWN,
'entry' => null
);
/**
* Result array
*
* @var array
*/
private $_hierarchyResults = null;
/**
* Root of the hierarchy
*
* @var Erfurt_Rdf_Resource
*/
private $_current = null;
/**
* URL object used to built URLs
*
* @var OntoWiki_Url
*/
private $_url = null;
/**
* Current session instance
*
* @var Zend_Session
*/
private $_session = null;
protected $_titleHelper = null;
/**
* Constructor
*
* @see OntoWiki_Model_Abstract
*/
public function __construct(Erfurt_Store $store, $graph, array $options = array())
{
parent::__construct($store, $graph);
$this->_options = array_merge($this->_options, $options);
$this->_current = (string)OntoWiki::getInstance()->selectedResource;
$this->_session = OntoWiki::getInstance()->session;
// HACK: if the graph itself is one that is normally ignored in other
// models, don't ignore it
if (in_array($this->_graph, $this->_options['ignore_ns'])) {
// TODO: remove only graph and imported namespaces
$this->_options['ignore_ns'] = array();
}
}
/**
* Returns whether the model contains data.
*
* @return boolean
*/
public function hasData()
{
if (!$this->_hierarchyResults) {
$this->getHierarchy();
}
return !empty($this->_hierarchyResults);
}
/**
* Returns the resource hierarchy.
*
* @return array
*/
public function getHierarchy()
{
if (!$this->_hierarchyResults) {
$query = $this->_buildQuery();
$this->_url = new OntoWiki_Url(array('route' => 'instances'), array('r', 'init'));
if ($result = $this->_model->sparqlQuery($query)) {
$this->_hierarchyResults = array();
// set titles
foreach ((array)$result as $row) {
$this->_titleHelper->addResource($row['classUri']);
if (!empty($row['sub'])) {
$this->_titleHelper->addResource($row['sub']);
}
}
foreach ((array)$result as $row) {
$classUri = $row['classUri'];
if (!array_key_exists($classUri, $this->_hierarchyResults)) {
$this->_hierarchyResults[$classUri] = $this->_getEntry($classUri, !empty($row['sub']));
$this->_titleHelper->addResource($classUri);
}
// do subclasses exists?
if (!empty($row['sub'])) {
$subClassUri = $row['sub'];
$this->_hierarchyResults[$classUri]['children'][$subClassUri]
= $this->_getEntry($subClassUri, !empty($row['subsub']));
}
}
}
}
return $this->_hierarchyResults;
}
protected function _getEntry($resultUri, $hasChildren = false)
{
$classes = '';
if ($resultUri == $this->_current) {
$classes .= ' selected';
}
if ($hasChildren) {
$classes .= ' has-children';
}
$this->_url->setParam('r', $resultUri, true);
$hierarchyOpen = is_array($this->_session->hierarchyOpen) &&
in_array($resultUri, $this->_session->hierarchyOpen);
$entry = array(
'uri' => $resultUri,
'url' => (string)$this->_url,
'classes' => trim($classes),
'title' => $this->_titleHelper->getTitle($resultUri, $this->_config->languages->locale),
'children' => array(),
'has_children' => $hasChildren,
'open' => $hierarchyOpen
);
return $entry;
}
protected function _buildQuery()
{
$query = new Erfurt_Sparql_SimpleQuery();
$query->setSelectClause('SELECT DISTINCT ?classUri ?sub ?subsub ?subsubsub');
$whereSpecs = array();
$whereSpec = '';
foreach ($this->_options['object_types'] as $type) {
$whereSpecs[] = '{?classUri a <' . $type . '>}';
}
// optional inference
if (!$this->_options['entry'] && $this->_inference) {
// instance retrieval is only applicable for classes
if ($this->_options['sub_relation'] == EF_RDFS_SUBCLASSOF) {
$whereSpecs[] = '{?instance a ?classUri.}';
}
// entities with a subtype must be a type
$whereSpecs[] = '{?subtype <' . $this->_options['sub_relation'] . '> ?classUri.}';
}
$whereSpec = implode(' UNION ', $whereSpecs);
$whereSpec .= ' FILTER (isURI(?classUri))';
// dont't show rdfs/owl entities and subtypes in the first level
if (!$this->_options['entry']) {
$whereSpec .= ' FILTER (regex(str(?super), "^' . EF_OWL_NS . '") || !bound(?super))';
}
$whereSpec .= ' OPTIONAL {?sub <' . $this->_options['sub_relation'] . '> ?classUri.
OPTIONAL {?subsub <' . $this->_options['sub_relation'] . '> ?sub.
OPTIONAL {?subsubsub <' . $this->_options['sub_relation'] . '> ?subsub}
}
}';
$whereSpec .= ' OPTIONAL {?classUri <' . $this->_options['sub_relation'] . '> ?super. FILTER(isUri(?super))}';
// namespaces to be ignored, rdfs/owl-defined objects
foreach ($this->_options['ignore_ns'] as $ignore) {
$whereSpec .= ' FILTER (!regex(str(?classUri), "^' . $ignore . '"))';
}
// entry point into the class tree
if ($this->_options['entry']) {
$whereSpec .= ' FILTER (str(?super) = str(<' . $this->_options['entry'] . '>))';
}
$query->setWherePart('WHERE {' . $whereSpec . '}');
return $query;
}
}
================================================
FILE: application/classes/OntoWiki/Model/Instances.php
================================================
* @author Jonas Brekle
*/
class OntoWiki_Model_Instances extends OntoWiki_Model
{
/**
* all triple (?s ?p ?o). is added and removed to the resorceQuery on demand, but always stored here
*
* @var Erfurt_Sparql_Query2_IF_TriplesSameSubject
*/
protected $_allTriple;
/**
* OntoWiki Application config
*
* @var Zend_Config
*/
protected $_config = null;
/**
* OntoWiki Application object
*
* @var OntoWiki
*/
protected $_owApp = null;
/**
* Properties whose values are to be fetched for each resource.
*
* @var array
*/
protected $_shownProperties = array();
/**
* @var array
*/
protected $_shownPropertiesConverted = array();
/**
* @var bool
*/
protected $_shownPropertiesConvertedUptodate = false;
/**
* @var array
*/
protected $_ignoredShownProperties
= array(//EF_RDF_TYPE
);
/**
* values of the set properties for all resources
*/
protected $_values;
/**
* @var bool
*/
protected $_valuesUptodate = false;
protected $_valueQueryUptodate = false;
/**
* all resources
*/
protected $_resources = array();
/**
* @var bool
*/
protected $_resourcesUptodate = false;
/**
*
* @var array transformed
*/
protected $_resourcesConverted;
/**
* @var bool
*/
protected $_resourcesConvertedUptodate = false;
/**
*
* @var Erfurt_Sparql_Query2_Var the var that is used in the resourcequery to bind all uri of list elements
*/
protected $_resourceVar = null;
/**
* @var array stores all configured filters
*/
protected $_filter = array();
/**
* Result array - what comes back when evaluating the query.
*
* @var array
*/
protected $_results = null;
/**
* @var bool
*/
protected $_resultsUptodate = false;
/**
* @var Erfurt_Sparql_Query2 the manged query that selects the resources in the list
*/
protected $_resourceQuery = null;
/**
* @var Erfurt_Sparql_Query2_IF_TriplesSameSubject
*/
protected $_sortTriple = null;
/**
* @var Erfurt_Sparql_Query2
*/
protected $_valueQuery = null;
/**
* @var Erfurt_Sparql_Query2_Filter
*/
protected $_valueQueryResourceFilter = null;
/**
* @var bool
*/
protected $_useCache = true;
/**
* @var OntoWiki_Model_TitleHelper
*/
protected $_titleHelper = null;
/**
* Constructor
*/
public function __construct(Erfurt_Store $store, Erfurt_Rdf_Model $model, $options = array())
{
parent::__construct($store, $model);
if (isset($options[Erfurt_Store::USE_CACHE])) {
$this->_useCache = $options[Erfurt_Store::USE_CACHE];
}
$this->_resourceQuery = new Erfurt_Sparql_Query2();
$this->_resourceVar = new Erfurt_Sparql_Query2_Var('resourceUri');
$this->_owApp = OntoWiki::getInstance();
$this->_config = $this->_owApp->config;
$this->_allTriple = new Erfurt_Sparql_Query2_Triple(
$this->_resourceVar,
new Erfurt_Sparql_Query2_Var('p'),
new Erfurt_Sparql_Query2_Var('o')
);
$this->addAllTriple();
//show resource uri
$this->_resourceQuery->addProjectionVar($this->_resourceVar);
$this->_resourceQuery
->setLimit(10) //per default query only for 10 resources
->setDistinct(true);
// when resourceVar is the object - prevent literals
$this->_resourceQuery->addFilter(
new Erfurt_Sparql_Query2_ConditionalAndExpression(
array(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_isBlank($this->_resourceVar)
)
)
)
);
//build value query
$this->_valueQuery = new Erfurt_Sparql_Query2();
$this->_valueQuery
->addProjectionVar($this->_resourceVar)
->setDistinct(true);
if (!isset($this->_config->lists) || $this->_config->lists->showTypeColumnByDefault === 'true') {
$this->addShownProperty(EF_RDF_TYPE, '__TYPE');
}
//set froms to the requested graph
$this->_valueQuery->addFrom((string)$model);
$this->_resourceQuery->addFrom((string)$model);
$this->invalidate();
}
/**
* dont keep the references to the query objects in $this->resourceQuery (the must be cloned too)
*/
public function __clone()
{
foreach ($this as $key => $val) {
if (is_object($val) || (is_array($val))) {
$this->{$key} = unserialize(serialize($val));
}
}
}
/**
* redirect calls that cant be handled - both to the resource and value query.
* currently only methods regarding the FROM are allowed
*
* @param string $name
* @param array $arguments
*/
public function __call($name, $arguments)
{
$allowedMethods = array(
'addFrom', 'addFroms', 'removeFrom', 'removeFroms',
'hasFrom', 'getFrom', 'getFroms', 'setFrom', 'setFroms'
);
if (in_array($name, $allowedMethods)
&& (method_exists($this->_valueQuery, $name) && method_exists($this->_resourceQuery, $name))
) {
call_user_func_array(array($this->_valueQuery, $name), $arguments);
$ret = call_user_func_array(array($this->_resourceQuery, $name), $arguments);
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
return $ret;
} else {
return $this;
}
} else {
throw new RuntimeException("OntoWiki_Model_Instances: method $name does not exists");
}
}
public function __sleep()
{
//dont save reference to the store
return array_diff(array_keys(get_object_vars($this)), array('_store', '_titleHelper', '_config', '_owApp'));
}
public function __wakeup()
{
//after serialisation, the store state may has been changed
$this->invalidate();
}
/**
*
* Method for setting the store explicitely
* (necessary after unserialization from session for unavailable _dbconn
* resource handles etc.)
*
* @param Erfurt_Store $store
*
* @throws Exception for parameter type being incorrect (no Erfurt_Store Object)
* @return null
*/
public function setStore(Erfurt_Store $store)
{
$this->_store = $store;
$this->restoreTitleHelper();
}
/**
*
* @throws OntoWiki_Exception
*/
protected function restoreTitleHelper()
{
$this->_titleHelper = new OntoWiki_Model_TitleHelper($this->_model, $this->_store);
}
/**
* set title helper (for unittests)
*
* @param OntoWiki_Model_TitleHelper $t
*/
public function setTitleHelper(OntoWiki_Model_TitleHelper $t)
{
$this->_titleHelper = $t;
}
/**
* get title helper (for unittests)
*
* @return OntoWiki_Model_TitleHelper
*/
public function getTitleHelper()
{
return $this->_titleHelper;
}
/**
* add ?resourceUri ?p ?o to the resource query
* TODO: support objects as resources? optionally?
*/
public function addAllTriple()
{
$this->_resourceQuery->addElement($this->_allTriple);
}
/**
* remove ?resourceUri ?p ?o from the resource query
*/
public function removeAllTriple()
{
$this->_allTriple->remove($this->_resourceQuery);
}
/**
* get the object that represents the "?resourceUri ?p ?o" from the resource query.
* object exists, even if not part of the query
*/
public function getAllTriple()
{
return $this->_allTriple;
}
/**
* Adds a property to the properties fetched for every resource.
*
* @param $propertyUri The URI of the property
* @param $propertyName Name to be used for the variable
*
* @return OntoWiki_Model_Instances
*/
public function addShownProperty(
$propertyUri,
$propertyName = null,
$inverse = false,
$datatype = null,
$hidden = false
) {
if (in_array($propertyUri, $this->_ignoredShownProperties)) {
return $this; //no action
}
if (!$propertyName) {
$propertyName = preg_replace('/^.*[#\/]/', '', $propertyUri);
$propertyName = str_replace('-', '', $propertyName);
}
$used = false;
foreach ($this->_shownProperties as $shownProp) {
if ($shownProp['name'] == $propertyName) {
$used = true;
}
}
//solve duplicate name problem by adding counter
if ($used) {
$counter = 2;
while ($used) {
$name = $propertyName . $counter;
++$counter;
$used = false;
foreach ($this->_shownProperties as $shownProp) {
if ($shownProp['name'] == $name) {
$used = true;
}
}
}
$propertyName = $name;
}
$ret = Erfurt_Sparql_Query2_Abstraction_ClassNode::addShownPropertyHelper(
$this->_valueQuery,
$this->_resourceVar,
$propertyUri,
$propertyName,
$inverse
);
$this->_shownProperties[$propertyUri . '-' . ($inverse ? 'inverse' : 'direct')] = array(
'uri' => $propertyUri,
'name' => $propertyName,
'inverse' => $inverse,
'datatype' => $datatype,
'varName' => $ret['var']->getName(),
'var' => $ret['var'],
'optionalpart' => $ret['optional'],
'filter' => $ret['filter'],
'hidden' => $hidden
);
$this->_valuesUptodate = false; // getValues will not use the cache next time
$this->_resultsUptodate = false;
return $this;
}
/**
* add a shown property, that is more complex.
* provide own triples, they will wrapped in an optional and a projection var will be added.
*
* @param array $triples
* @param Erfurt_Sparql_Query2_Var $var
* @param boolean $hidden
*
* @return OntoWiki_Model_Instances
*/
public function addShownPropertyCustom($triples, $var, $hidden = false)
{
//add
$optional = new Erfurt_Sparql_Query2_OptionalGraphPattern();
$optional->addElements($triples);
$this->_valueQuery->getWhere()->addElement($optional);
$this->_valueQuery->addProjectionVar($var);
//save
$this->_shownProperties['custom' . count($this->_shownProperties)] = array(
'uri' => null,
'name' => 'custom' . count($this->_shownProperties),
'inverse' => false,
'datatype' => null,
'varName' => $var->getName(),
'var' => $var,
'optionalpart' => $triples,
'filter' => array(),
'hidden' => $hidden
);
$this->_valuesUptodate = false; // getValues will not use the cache next time
$this->_resultsUptodate = false;
return $this;
}
/**
* remove a property that has been added before
*
* @param string $key the uri
*/
public function removeShownProperty($property, $inverse)
{
$key = $property . '-' . ($inverse ? 'inverse' : 'direct');
if (isset($this->_shownProperties[$key])) {
$prop = $this->_shownProperties[$key];
$this->_valueQuery->removeProjectionVar($prop['var']);
$prop['optionalpart']->remove($this->_valueQuery);
unset($this->_shownProperties[$key]);
return true;
} else {
return false;
}
}
/**
* queries for values (unconverted)
*
* @return array
*/
public function getResults()
{
$this->updateValueQuery();
if (!$this->_resultsUptodate) {
$this->_results = $this->_store->sparqlQuery(
$this->_valueQuery,
array(
Erfurt_Store::RESULTFORMAT => Erfurt_Store::RESULTFORMAT_EXTENDED,
Erfurt_Store::USE_CACHE => $this->_useCache
)
);
$this->_resultsUptodate = true;
}
return $this->_results;
}
/**
* add a filter from the filter box - these filters match some predefined schemes
* (like "equals", "contains")
*
* @param string $property
* @param boolean $isInverse whether the property is a indirect property of the resources
* @param string $propertyLabel label affects the created variable
* @param string $filter the type of filter ("equals", "bound", "larger", "smaller", "between", "contains")
* @param string $value
* @param string $valueSecondary
* @param string $valuetype ("uri" or "literal" or "typed-literal")
* @param string $literaltype (if valuetype is set to "typed-literal", you can pass a URI here)
* @param boolean $hidden whether to hide this filter in the filter box GUI
* @param string $id optional predined ID, will be generated normally
* @param boolean $negate whether to invert the condition
* @param boolean $optional
*
* @return string id
* @throws RuntimeException
*/
public function addFilter(
$property,
$isInverse,
$propertyLabel,
$filter,
$value = null,
$valueSecondary = null,
$valuetype = 'literal',
$literaltype = null,
$hidden = false,
$id = null,
$negate = false,
$optional = false
) {
if ($id == null) {
$id = 'box' . count($this->_filter);
} else {
if (isset($this->_filter[$id])) {
$this->removeFilter($id);
}
}
$prop = new Erfurt_Sparql_Query2_IriRef($property);
if (!empty($value)) {
switch ($valuetype) {
case 'uri':
$valueObj = new Erfurt_Sparql_Query2_IriRef($value);
if (!empty($valueSecondary)) {
$valueSecondaryObj = new Erfurt_Sparql_Query2_IriRef($valueSecondary);
}
break;
case 'literal':
if (!empty($literaltype)) {
//with language tags
$valueObj = new Erfurt_Sparql_Query2_RDFLiteral(
$value,
$literaltype
);
if (!empty($valueSecondary)) {
$valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral(
$valueSecondary,
$literaltype
);
}
} else {
//no language tags
if (is_array($value)) {
$value = current($value);
}
$meta = '';
if (is_scalar($value) && !is_string($value) && !is_array($value)) {
$meta = gettype($value);
}
$valueObj = new Erfurt_Sparql_Query2_RDFLiteral($value, $meta);
if (!empty($valueSecondary)) {
$valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral($valueSecondary, $meta);
}
}
break;
case 'typed-literal':
if (in_array($literaltype, Erfurt_Sparql_Query2_RDFLiteral::$knownShortcuts)) {
//is something like "bool" or "int" - will be converted from "1"^^xsd:int to 1
$valueObj = new Erfurt_Sparql_Query2_RDFLiteral($value, $literaltype);
if (!empty($valueSecondary)) {
$valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral($valueSecondary, $literaltype);
}
} else {
// is a uri
$valueObj = new Erfurt_Sparql_Query2_RDFLiteral(
$value,
new Erfurt_Sparql_Query2_IriRef($literaltype)
);
if (!empty($valueSecondary)) {
$valueSecondaryObj = new Erfurt_Sparql_Query2_RDFLiteral(
$valueSecondary,
new Erfurt_Sparql_Query2_IriRef($literaltype)
);
}
}
break;
default:
throw new RuntimeException(
'called Ontowiki_Model_Instances::addFilter with ' .
'unknown param-value: valuetype = "' . $valuetype . '"'
);
}
}
switch ($filter) {
case 'contains':
$var = new Erfurt_Sparql_Query2_Var($propertyLabel);
if (!$isInverse) {
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$prop,
$var
);
} else {
$triple = $this->_resourceQuery->addTriple(
$var,
$prop,
$this->_resourceVar
);
}
$valueObj->setValue(str_replace("\\", "\\\\", preg_quote($valueObj->getValue())));
$addFilter = null;
if (!$negate) {
$addFilter = new Erfurt_Sparql_Query2_Regex(
new Erfurt_Sparql_Query2_Str($var),
$valueObj
);
} else {
$addFilter = new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_Regex(
new Erfurt_Sparql_Query2_Str($var),
$valueObj
)
);
}
$filterObj = $this->_resourceQuery->addFilter($addFilter);
break;
case 'equals':
if ($valuetype == 'literal') {
$valueVar = new Erfurt_Sparql_Query2_Var($propertyLabel);
if (!$isInverse) {
$triple = new Erfurt_Sparql_Query2_Triple(
$this->_resourceVar,
$prop,
$valueVar
);
} else {
throw new RuntimeException(
'literal as value for an inverse property ' .
'is a literal subject which is not allowed'
);
}
if ($negate) {
$optionalGP = new Erfurt_Sparql_Query2_OptionalGraphPattern();
$optionalGP->addElement($triple);
if ($optional) {
$orExpression = new Erfurt_Sparql_Query2_ConditionalOrExpression();
$orExpression->addElement(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_bound($valueVar)
)
);
$orExpression->addElement(new Erfurt_Sparql_Query2_NotEquals($valueVar, $valueObj));
$filterObj = $optionalGP->addFilter($orExpression);
} else {
$filterObj = $optionalGP->addFilter(
new Erfurt_Sparql_Query2_NotEquals($valueVar, $valueObj)
);
}
$this->_resourceQuery->addElement($optionalGP);
$triple = $optionalGP;
} else {
$this->_resourceQuery->addElement($triple);
$filterObj = $this->_resourceQuery->addFilter(
new Erfurt_Sparql_Query2_Regex(
new Erfurt_Sparql_Query2_Str($valueVar),
new Erfurt_Sparql_Query2_RDFLiteral(
'^' . str_replace("\\", "\\\\", preg_quote($value)) . '$'
)
)
);
}
} else {
if (!$isInverse) {
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$prop,
$valueObj
);
} else {
$triple = $this->_resourceQuery->addTriple(
$valueObj,
$prop,
$this->_resourceVar
);
}
}
break;
case 'larger':
$var = new Erfurt_Sparql_Query2_Var($propertyLabel);
if (!$isInverse) {
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$prop,
$var
);
} else {
$triple = $this->_resourceQuery->addTriple(
$var,
$prop,
$this->_resourceVar
);
}
$filterObj = $this->_resourceQuery->addFilter(
new Erfurt_Sparql_Query2_Larger($var, $valueObj)
);
break;
case 'smaller':
$var = new Erfurt_Sparql_Query2_Var($propertyLabel);
if (!$isInverse) {
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$prop,
$var
);
} else {
$triple = $this->_resourceQuery->addTriple(
$var,
$prop,
$this->_resourceVar
);
}
$filterObj = $this->_resourceQuery->addFilter(
new Erfurt_Sparql_Query2_Smaller($var, $valueObj)
);
break;
case 'between':
$var = new Erfurt_Sparql_Query2_Var($propertyLabel);
if (!$isInverse) {
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$prop,
$var
);
} else {
$triple = $this->_resourceQuery->addTriple(
$var,
$prop,
$this->_resourceVar
);
}
$filterObj = $this->_resourceQuery->addFilter(
new Erfurt_Sparql_Query2_ConditionalAndExpression(
array(
new Erfurt_Sparql_Query2_Larger($var, $valueObj),
new Erfurt_Sparql_Query2_Smaller($var, $valueSecondaryObj)
)
)
);
break;
case 'bound':
$var = new Erfurt_Sparql_Query2_Var($propertyLabel);
if (!$isInverse) {
$triple = new Erfurt_Sparql_Query2_Triple(
$this->_resourceVar,
$prop,
$var
);
} else {
$triple = new Erfurt_Sparql_Query2_Triple(
$var,
$prop,
$this->_resourceVar
);
}
if ($negate) {
$optionalGP = new Erfurt_Sparql_Query2_OptionalGraphPattern();
$optionalGP->addElement($triple);
$this->_resourceQuery->addElement($optionalGP);
$triple = $optionalGP; // to save this obj (see underneath 20 lines)
} else {
$this->_resourceQuery->addElement($triple);
}
if ($negate) {
$filterObj = $this->_resourceQuery->addFilter(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_bound($var)
)
);
}
break;
default:
throw new RuntimeException(
'called Ontowiki_Model_Instances::addFilter with ' .
'unknown param-value: filtertype=' . $filter
);
}
//these filters bring their own triple
$this->removeAllTriple();
//save
$this->_filter[$id] = array(
'id' => $id,
'mode' => 'box',
'property' => $property,
'isInverse' => $isInverse,
'propertyLabel' => $propertyLabel,
'filter' => $filter,
'value1' => $value,
'value2' => $valueSecondary,
'valuetype' => $valuetype,
'literaltype' => $literaltype,
'hidden' => $hidden,
'negate' => $negate,
'objects' => array($triple, isset($filterObj) ? $filterObj : null)
);
$this->invalidate();
return $id;
}
/**
* remove a filter by id
*
* @param string $id
*
* @return OntoWiki_Model_Instances $this
*/
public function removeFilter($id)
{
if (isset($this->_filter[$id])) {
foreach ($this->_filter[$id]['objects'] as $obj) {
if ($obj instanceof Erfurt_Sparql_Query2_ElementHelper) {
$obj->remove($this->_resourceQuery);
}
}
unset($this->_filter[$id]);
//when all deleted
//empty == 1 left because this last element is the "isUri and !isBlank"-filter
if (count($this->_resourceQuery->getWhere()->getElements()) == 1) {
$this->addAllTriple();
}
$this->invalidate();
return $this;
}
}
/**
* get the internal array that holds the filters
*
* @return array
*/
public function getFilter()
{
return $this->_filter;
}
/**
*
* @param string $type the uri of the class
* @param string $id
* @param array $options
*
* @return int id
*/
public function addTypeFilter($type, $id = null, $option = array())
{
if ($id == null) {
$id = 'type' . count($this->_filter);
} else {
if (isset($this->_filter[$id])) {
$this->removeFilter($id);
}
}
//shortcut navigation - only a rdfs class given
$options['mode'] = 'instances';
$options['type'] = $type;
$options['memberPredicate'] = EF_RDF_TYPE;
$options['withChilds'] = isset($option['withChilds']) ? $option['withChilds'] : true;
$options['hierarchyUp'] = EF_RDFS_SUBCLASSOF;
$options['hierarchyIsInverse'] = true;
$options['direction'] = 1; // down the tree
$memberPredicate = $options['memberPredicate'];
if (is_string($memberPredicate)) {
$memberPredicate = new Erfurt_Sparql_Query2_IriRef($memberPredicate);
}
if (!($memberPredicate instanceof Erfurt_Sparql_Query2_Verb)) {
throw new RuntimeException(
'Option "member_predicate" passed to Ontowiki_Model_Instances ' .
'must be an instance of Erfurt_Sparql_Query2_IriRef ' .
'or string instance of ' . typeHelper($memberPredicate) . ' given'
);
}
$type = new Erfurt_Sparql_Query2_IriRef($options['type']);
$subClasses = array();
if ($options['withChilds']) {
$subClasses = array_keys(
// get subclasses:
$this->_store->getTransitiveClosure(
$this->_graph,
$options['hierarchyUp'],
array($type->getIri()),
$options['hierarchyIsInverse']
)
);
} else {
if (isset($options['subtypes'])) { //dont query, take the given. maybe the new navigation can use this
$subClasses = $options['subtypes'];
} else {
$subClasses = array();
}
}
if (count($subClasses) > 1) {
// there are subclasses. "1" because the class itself is somehow included in the subclasses...
$typeVar = new Erfurt_Sparql_Query2_Var($type);
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$memberPredicate,
$typeVar
);
$or = new Erfurt_Sparql_Query2_ConditionalOrExpression();
foreach ($subClasses as $subclass) {
$or->addElement(
new Erfurt_Sparql_Query2_Equals(
$typeVar,
new Erfurt_Sparql_Query2_IriRef($subclass)
)
);
}
$filterObj = $this->_resourceQuery->addFilter($or);
} else {
// no subclasses
$triple = $this->_resourceQuery->addTriple(
$this->_resourceVar,
$memberPredicate,
new Erfurt_Sparql_Query2_IriRef($type->getIri())
);
}
//save
$this->_filter[$id] = array(
'id' => $id,
'mode' => 'rdfsclass',
'rdfsclass' => $options['type'],
'withChilds' => $options['withChilds'],
'objects' => array($triple, isset($filterObj) ? $filterObj : null)
);
//these filters bring there own triple
$this->removeAllTriple();
$this->invalidate();
return $id;
}
public function addDisjunctiveTypeFilters(array $types, $id = null, array $options = array())
{
if (!$id) {
$id = 'type' . count($this->_filter);
} else {
if (isset($this->_filter[$id])) {
$this->removeFilter($id);
}
}
// Create UNION of all types
$union = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
foreach ($types as $type) {
$union->addElement(
new Erfurt_Sparql_Query2_GroupGraphPattern(
new Erfurt_Sparql_Query2_Triple(
$this->_resourceVar,
new Erfurt_Sparql_Query2_IriRef(EF_RDF_TYPE),
new Erfurt_Sparql_Query2_IriRef($type)
)
)
);
}
// Add UNION element
$this->_resourceQuery->addElement($union);
// Remove default ?s ?p ?o pattern
$this->_allTriple->remove($this->_resourceQuery);
}
/**
*
* @param string $str
* @param string $id optional
*
* @return string the id used
*/
public function addSearchFilter($str, $id = null)
{
if ($id == null) {
$id = 'search' . count($this->_filter);
} else {
if (isset($this->_filter[$id])) {
$this->removeFilter($id);
}
}
$pattern = $this->_store->getSearchPattern(
$str,
$this->_graph
);
$vars = array();
foreach ($pattern as $element) {
if (method_exists($element, 'getVars')) {
$vars = array_merge($vars, $element->getVars());
}
}
$count = count($this->_filter);
foreach ($vars as $var) {
if ($var->getName() == 'o' || $var->getName() == 'p') {
$var->setName($var->getName() . $count);
}
}
$this->_resourceQuery->addElements($pattern);
//save
$this->_filter[$id] = array(
'id' => $id,
'mode' => 'search',
'searchText' => $str,
'objects' => $pattern
);
//these filters bring there own triple
$this->removeAllTriple();
$this->invalidate();
return $id;
}
/**
* add arbitrary triples to the query to filter (used by the navigation)
*
* @param array $triples
* @param string $id
*
* @return string the id used
*/
public function addTripleFilter($triples, $id = null)
{
if ($id == null) {
$id = 'triple' . count($this->_filter);
} else {
if (isset($this->_filter[$id])) {
$this->removeFilter($id);
}
}
$this->_resourceQuery->addElements($triples);
//save
$this->_filter[$id] = array(
'id' => $id,
'mode' => 'triples',
'objects' => $triples
);
//these filters bring there own triple
$this->removeAllTriple();
$this->invalidate();
return $id;
}
/**
* get the query used to get the values (shownproperties)
*
* @deprecated
* @see getValueQuery
* @return Erfurt_Sparql_Query2
*/
public function getQuery()
{
return $this->getValueQuery();
}
/**
* get the query used to get the values (shownproperties)
*
* @return Erfurt_Sparql_Query2
*/
public function getValueQuery()
{
$this->updateValueQuery();
return $this->_valueQuery;
}
/**
* get the query used for getting the resources. incl. filter
*
* @return Erfurt_Sparql_Query2
*/
public function getResourceQuery()
{
return $this->_resourceQuery;
}
/**
* build a link that recreates the current state on a different system
*
* @return string
*/
public function getPermalink($listname)
{
$url = new OntoWiki_Url();
$url->init = true;
if ($this->getOffset() != 0 && $this->getLimit() != 0) {
$url->p = (($this->getOffset() / $this->getLimit()) + 1);
}
if ($this->getLimit() != 10) {
$url->limit = $this->getLimit();
}
$url->list = $listname;
$conf = array();
if (is_array($this->_shownProperties) && count($this->_shownProperties) > 0) {
$conf['shownProperties'] = array();
foreach ($this->_shownProperties as $shownProperty) {
$conf['shownProperties'][] = array(
'uri' => $shownProperty['uri'],
'label' => $shownProperty['name'],
'inverse' => $shownProperty['inverse'],
'action' => 'add'
);
}
}
if (is_array($this->_filter) && count($this->_filter) > 0) {
$conf['filter'] = array();
foreach ($this->_filter as $filter) {
switch ($filter['mode']) {
case 'box':
$arr = array(
'action' => 'add',
'mode' => 'box'
);
$arr = array_merge($arr, $filter);
$conf['filter'][] = $arr;
break;
case 'search':
$conf['filter'][] = array(
'action' => 'add',
'mode' => 'search',
'searchText' => $filter['searchText']
);
break;
case 'rdfsclass':
$conf['filter'][] = array(
'action' => 'add',
'mode' => 'rdfsclass',
'rdfsclass' => $filter['rdfsclass']
);
break;
case 'triples':
//problem: php objects can not be json encoded ...
break;
}
}
$url->m = (string)$this->_model;
if (!empty($conf)) {
$url->instancesconfig = json_encode($conf);
}
}
return $url;
}
/**
* @return Erfurt_sparql_Query2_Var the var that is used as subject in the query
*/
public function getResourceVar()
{
return $this->_resourceVar;
}
/**
* Returns the property values for all resources at once.
* This method receives its values from Resources from the ResourcePool.
* @return array
*/
public function getValues()
{
if (empty($this->_resources)) {
return array();
}
//first we have to create the list of resources that have to be shown.
$pool = Erfurt_App::getInstance()->getResourcePool();
$resources = array();
$valueResults = array();
foreach ($this->_resources as $item) {
$resourceUri = $item['value'];
$resource = $pool->getResource($resourceUri, (string)$this->_model);
//secondly we have to walk throw the list of interesting properties to bw shown
$valueResults[$resourceUri] = array();
foreach ($this->_shownProperties as $key => $property) {
$propertyUri = $property['uri'];
$variable = $property['var']->getName();
$propertyResource = $pool->getResource($propertyUri, (string)$this->_model);
//now we have to extract the values according the current property from the resource
$values = $resource->getMemoryModel()->getValues($resourceUri, $propertyUri);
foreach ($values as $value) {
//initialising the value with the original content
$revisedValue = $value['value'];
$link = null;
//but we have to do something specific if the value is a resource
if ($value['type'] == 'uri') {
// skip blanknode values here due to backend problems with filters
if (substr($value['value'], 0, 2) == '_:') {
continue;
}
$url = new OntoWiki_Url(array('route' => 'properties'), array('r'));
$link = (string)$url->setParam('r', $value['value'], true);
$event = new Erfurt_Event('onDisplayObjectPropertyValue');
$event->property = $propertyUri;
$event->value = $value['value'];
$revisedValue = $event->trigger();
// set default if event has not been handled
if (!$event->handled()) {
$revisedValue = $this->_titleHelper->getTitle($value['value']);
}
} else { // the value is not a resource but a literal value
$event = new Erfurt_Event('onDisplayLiteralPropertyValue');
$event->property = $propertyUri;
$event->value = $value['value'];
$event->setDefault($value['value']);
$revisedValue = $event->trigger();
}
//now we have to assign the facts to the result array
$valueResults[$resourceUri][$variable][] = array(
'value' => $revisedValue,
'origvalue' => $value['value'],
'type' => $value['type'],
'url' => $link,
'uri' => $value['value'] //TODO: rename (can be literal)
);
}
}
}
//some assignments
$this->_values = $valueResults;
$this->_valuesUptodate = true;
//returning the result
return $valueResults;
}
/**
* Returns the property values for all resources at once.
* This method generate one SPARQL query to receive all values .
* Original Name was getValues()
* @return array
*/
public function getValuesBySingleQuery()
{
if ($this->_valuesUptodate) {
return $this->_values;
} else {
$this->updateValueQuery();
}
if (empty($this->_resources)) {
return array();
}
$this->getResults();
$result = array();
if (isset($this->_results['results']['bindings'])) {
$result = $this->_results['results']['bindings'];
}
//fill titlehelper
foreach ($result as $row) {
foreach ($this->_shownProperties as $property) {
if (isset($row[$property['varName']])
&& $row[$property['varName']]['type'] == 'uri'
&& substr($row[$property['varName']]['value'], 0, 2) != '_:'
) {
$this->_titleHelper->addResource($row[$property['varName']]['value']);
}
}
if (isset($row['__TYPE']) && $row['__TYPE']['type'] == 'uri' //sould both be true
) {
$this->_titleHelper->addResource($row['__TYPE']['value']);
}
$this->_titleHelper->addResource($row[$this->_resourceVar->getName()]['value']);
}
$valueResults = array();
foreach ($result as $row) {
$resourceUri = $row[$this->_resourceVar->getName()]['value'];
if (!array_key_exists($resourceUri, $valueResults)) {
$valueResults[$resourceUri] = array();
}
$url = new OntoWiki_Url(array('route' => 'properties'), array('r'));
$value = null;
$link = null;
foreach ($row as $varName => $data) {
if (!isset($valueResults[$resourceUri][$varName])) {
$valueResults[$resourceUri][$varName] = array();
}
if ($data['type'] == 'uri') {
if (substr($data['value'], 0, 2) == '_:') {
continue; // skip blanknode values here due to backend problems with filters
}
// object type is uri --> handle object property
$objectUri = $data['value'];
$url->setParam('r', $objectUri, true);
$link = (string)$url;
// set up event
$event = new Erfurt_Event('onDisplayObjectPropertyValue');
//find uri
foreach ($this->_shownProperties as $property) {
if ($varName == $property['varName']) {
$event->property = $property['uri'];
}
}
$event->value = $objectUri;
// trigger
$value = $event->trigger();
// set default if event has not been handled
if (!$event->handled()) {
$value = $this->_titleHelper->getTitle($objectUri);
}
} else {
// object is a literal
$object = $data['value'];
$propertyUri = null;
foreach ($this->_shownProperties as $property) {
if ($varName == $property['varName']) {
$propertyUri = $property['uri'];
}
}
if ($object !== null) {
// set up event
$event = new Erfurt_Event('onDisplayLiteralPropertyValue');
$event->property = $propertyUri;
$event->value = $object;
$event->setDefault($object);
// trigger
$value = $event->trigger();
}
}
//check for dulplicate values
if (isset($valueResults[$resourceUri][$varName])) {
foreach ($valueResults[$resourceUri][$varName] as $old) {
if ($old['origvalue'] == $data['value'] && $old['type'] == $data['type']) {
$link = null;
continue 2; // dont add this value
}
}
}
//add value
$valueResults[$resourceUri][$varName][] = array(
'value' => $value,
'origvalue' => $data['value'],
'type' => $data['type'],
'url' => $link,
'uri' => $data['value'] //TODO: rename (can be literal) -> use origvalue + type to output uri
);
$value = null;
$link = null;
}
}
foreach ($this->getShownResources() as $resource) {
if (!isset($valueResults[$resource['value']])) {
//there are no statements about this resource
$valueResults[$resource['value']] = array();
}
}
$this->_values = $valueResults;
$this->_valuesUptodate = true;
return $valueResults;
}
public function getAllPropertiesQuery($inverse = false)
{
$query = clone $this->_resourceQuery;
$query
->removeAllProjectionVars()
->setDistinct(true)
->setLimit(0)
->setOffset(0);
$vars = $query->getWhere()->getVars();
$resourceVar = $this->getResourceVar();
foreach ($vars as $var) {
if ($var->getName() == $resourceVar->getName()) {
$var->setName('listresource');
}
}
$listResource = new Erfurt_Sparql_Query2_Var('listresource');
$predVar = new Erfurt_Sparql_Query2_Var('resourceUri');
if (!$inverse) {
$query->addTriple(
$listResource,
$predVar,
new Erfurt_Sparql_Query2_Var('showPropsObj')
);
} else {
$query->addTriple(
new Erfurt_Sparql_Query2_Var('showPropsSubj'),
$predVar,
$listResource
);
}
$query
->addProjectionVar($predVar)
->getOrder()
->clear();
return $query;
}
/**
* Returns a list of properties used by the current list of resources.
* Original Name was getValues()
* @return array
*/
public function getAllProperties($inverse = false)
{
if ((empty($this->_resources) && $this->_resourcesUptodate)) {
return array();
}
$pool = Erfurt_App::getInstance()->getResourcePool();
$propertyUris = array();
$memoryModel = new Erfurt_Rdf_MemoryModel();
foreach ($this->_resources as $item) {
$resourceUri = $item['value'];
$resource = $pool->getResource($resourceUri, (string)$this->_model);
if ($inverse == false) {
$resourceDescription = $resource->getDescription();
$memoryModel->addStatements($resourceDescription);
} else {
$resourceDescription = $resource->getDescription(array('fetchInverse' => true));
$memoryModel->addStatements($resourceDescription);
//remove s from memory model to extract only inverse relations
$memoryModel->removeS($resourceUri);
}
}
$predicates = $memoryModel->getPredicates();
foreach ($predicates as $uri) {
$propertyUris[] = array('uri' => $uri);
}
return $this->convertProperties($propertyUris);
}
/**
* Returns the list of properties used by all resources at once.
* This method generate one SPARQL query .
* Original Name was getAllProperties()
* @return array
*/
public function getAllPropertiesBySingleQuery($inverse = false)
{
if (empty($this->_resources) && $this->_resourcesUptodate) {
return array();
}
$query = $this->getAllPropertiesQuery($inverse);
$results = $this->_store->sparqlQuery(
$query,
array(
Erfurt_Store::RESULTFORMAT => Erfurt_Store::RESULTFORMAT_EXTENDED,
Erfurt_Store::USE_CACHE => $this->_useCache
)
);
$properties = array();
foreach ($results['results']['bindings'] as $row) {
$properties[] = array('uri' => $row['resourceUri']['value']);
}
return $this->convertProperties($properties);
}
/**
* get the bound values for a predicate
*
* @param Erfurt_Sparql_Query2_IriRef|string $property
* @param boolean $distinct
* @param boolean $inverse
*
* @return array
*/
public function getPossibleValues($property, $distinct = true, $inverse = false)
{
if (is_string($property)) {
$property = new Erfurt_Sparql_Query2_IriRef($property);
}
if (!($property instanceof Erfurt_Sparql_Query2_IriRef)) {
throw new RuntimeException(
'Argument 1 passed to OntoWiki_Model_Instances::getObjects ' .
'must be instance of string or Erfurt_Sparql_Query2_IriRef, ' .
typeHelper($property) . ' given'
);
}
$query = clone $this->_resourceQuery;
$query
->removeAllProjectionVars()
->setDistinct($distinct)
->setLimit(0)
->setOffset(0);
$valueVar = new Erfurt_Sparql_Query2_Var('obj');
if ($inverse) {
$query->addTriple($valueVar, $property, $this->_resourceVar);
} else {
$query->addTriple($this->_resourceVar, $property, $valueVar);
}
$query->addFilter(
new Erfurt_Sparql_Query2_ConditionalAndExpression(
array(
// when resourceVar is the object - prevent literals
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_isBlank($valueVar)
)
)
)
);
$query->addProjectionVar($valueVar);
$results = $this->_store->sparqlQuery(
$query,
array(
Erfurt_Store::RESULTFORMAT => Erfurt_Store::RESULTFORMAT_EXTENDED,
Erfurt_Store::USE_CACHE => $this->_useCache
)
);
$values = array();
foreach ($results['results']['bindings'] as $row) {
$values[] = $row['obj'];
}
return $values;
}
/**
* get link-url, curi, title for an array of properties
*
* @param array $properties
*
* @return array
*/
protected function convertProperties($properties)
{
$uris = array();
foreach ($properties as $property) {
$uris[] = $property['uri'];
}
if (!empty($properties)) {
$this->_titleHelper->addResources($uris);
$url = new OntoWiki_Url(array('route' => 'properties'), array('r'));
}
$propertyResults = array();
foreach ($properties as $key => $property) {
if (in_array($property['uri'], $this->_ignoredShownProperties)) {
continue;
}
// set URL
$url->setParam('r', $property['uri'], true);
$property['url'] = (string)$url;
$property['curi'] = OntoWiki_Utils::contractNamespace($property['uri']);
$property['title'] = $this->_titleHelper->getTitle($property['uri']);
$propertyResults[$key] = $property;
}
return $propertyResults;
}
/**
* Returns information about the properties fetched (title etc.)
*
* @return array
*/
public function getShownProperties()
{
if ($this->_shownPropertiesConvertedUptodate) {
// TODO is this required here?
echo 'reuse';
return $this->_shownPropertiesConverted;
}
//$this->getResults();
$converted = $this->convertProperties($this->_shownProperties);
$this->_shownPropertiesConverted = $converted;
$this->_shownPropertiesConvertedUptodate = true;
return $converted;
}
/**
* array of shownproperties (each is a array:
* array (
* 'uri'
'name'
'inverse'
'datatype'
'varName'
'var' // var objectused as object
'optionalpart' //the hole optional {?resourceUri ?var} pattern object
'filter' // the FILTER(!isBlank(?var)) object
* )
*
* @return array
*/
public function getShownPropertiesPlain()
{
return $this->_shownProperties;
}
/**
* get titles and build link-urls (for a sparql result of the resource query)
*
* @param array $resources an array of resource uris
*
* @return array
*/
public function convertResources($resources)
{
// add titles first, seperatly
$uris = array();
foreach ($resources as $resource) {
$uris[] = $resource['value'];
}
$this->_titleHelper->addResources($uris);
$resourceResults = array();
foreach ($resources as $resource) {
$thisResource = $resource;
$thisResource['uri'] = $resource['value'];
// the URL to view this resource in detail
$url = new OntoWiki_Url(array('controller' => 'resource', 'action' => 'properties'), array());
$url->r = $resource['value'];
$thisResource['url'] = (string)$url;
// title
$thisResource['title'] = $this->_titleHelper->getTitle($resource['value']);
$resourceResults[] = $thisResource;
}
return $resourceResults;
}
protected function getShownResources()
{
if (!$this->_resourcesUptodate) {
$result = $this->_store->sparqlQuery(
$this->_resourceQuery,
array(
Erfurt_Store::RESULTFORMAT => Erfurt_Store::RESULTFORMAT_EXTENDED,
Erfurt_Store::USE_CACHE => $this->_useCache
)
);
$this->_resources = array();
foreach ($result['results']['bindings'] as $row) {
if (isset($row[$this->_resourceVar->getName()])) {
$this->_resources[] = $row[$this->_resourceVar->getName()];
} else {
throw new Erfurt_Exception(
'The given query is not a valid resource query because no variable with' .
'name: "' . $this->_resourceVar->getName() . '" is specified.'
);
}
}
$this->_resourcesUptodate = true;
}
return $this->_resources;
}
/**
* Returns information about the resources queried
*
* @return array
*/
public function getResources()
{
if ($this->_resourcesConvertedUptodate) {
return $this->_resourcesConverted;
}
$this->_resourcesConverted = $this->convertResources($this->getShownResources());
$this->_resourcesConvertedUptodate = true;
return $this->_resourcesConverted;
}
/**
* Returns whether the model has data.
*
* @return boolean
*/
public function hasData()
{
$this->getShownResources();
return !empty($this->_resources);
}
/**
* Sets the maximum number of resources to fetch for one page.
*
* @param int $limit
*
* @return OntoWiki_Model_Instances
*/
public function setLimit($limit)
{
if ($this->_resourceQuery->getLimit() == $limit) {
return $this;
}
if ($limit < 0) {
$limit *= -1;
}
$this->_resourceQuery->setLimit($limit);
$this->invalidate();
return $this;
}
/**
* Sets the number of resources to be skipped for the current page.
*
* @param int $offset
*
* @return OntoWiki_Model_Instances
*/
public function setOffset($offset)
{
if ($this->_resourceQuery->getOffset() == $offset) {
return $this;
}
if ($offset < 0) {
$offset *= -1;
}
$this->_resourceQuery->setOffset($offset);
$this->invalidate();
return $this;
}
/** Gets the maximum number of resources to fetch for one page.
*
* @return int
*/
public function getLimit()
{
return $this->_resourceQuery->getLimit();
}
/**
* Gets the number of resources to be skipped for the current page.
*
* @return int
*/
public function getOffset()
{
return $this->_resourceQuery->getOffset();
}
/*
* set all "uptodate" flags to false
* @return OntoWiki_Model_Instances
*/
public function invalidate()
{
$this->_resourcesConvertedUptodate = false;
$this->_resourcesUptodate = false;
$this->_shownPropertiesConvertedUptodate = false;
$this->_resultsUptodate = false;
$this->_valuesUptodate = false;
$this->_valueQueryUptodate = false;
return $this;
}
/**
* if the selected resources changed (due to filters or limit or offset)
* we have to change the value query as well (because the resources are mentioned as subjects)
*
* @return OntoWiki_Model_Instances $this
*/
protected function updateValueQuery()
{
if ($this->_valueQueryUptodate) {
return $this;
}
$resources = $this->getShownResources();
foreach ($resources as $key => $resource) {
$resources[$key] = new Erfurt_Sparql_Query2_SameTerm(
$this->_resourceVar,
new Erfurt_Sparql_Query2_IriRef($resource['value'])
);
}
if ($this->_valueQueryResourceFilter == null) {
$this->_valueQueryResourceFilter = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_BooleanLiteral(false)
);
$this->_valueQuery->addElement($this->_valueQueryResourceFilter);
}
if (!empty($resources)) {
$constraint = new Erfurt_Sparql_Query2_ConditionalOrExpression($resources);
} else {
$constraint = new Erfurt_Sparql_Query2_BooleanLiteral(false);
}
$this->_valueQueryResourceFilter->setConstraint($constraint);
//fix for a strange issue where a query with only optionals fails
//(but there is a magic/unkown condition, that makes it work for some queries!?)
$hasTriple = false;
foreach ($this->_valueQuery->getWhere()->getElements() as $element) {
if ($element instanceof Erfurt_Sparql_Query2_IF_TriplesSameSubject) {
$hasTriple = true;
break;
}
}
if (!$hasTriple) {
$this->_valueQuery->getWhere()->addElement(
new Erfurt_Sparql_Query2_Triple(
$this->_resourceVar,
new Erfurt_Sparql_Query2_Var('p'),
new Erfurt_Sparql_Query2_Var('o')
)
);
}
//remove duplicate triples...
$this->_valueQuery->optimize();
$this->_valueQueryUptodate = true;
return $this;
}
/**
* order by a property (must be set as shown property before)
*
* @param type $uri the property to order by
* @param boolean $asc true if ascending, false if descending
*/
public function setOrderProperty($uri, $asc = true)
{
$this->setOffset(0);
if ($this->_sortTriple == null) {
$orderVar = new Erfurt_Sparql_Query2_Var('order');
$this->_sortTriple = new Erfurt_Sparql_Query2_OptionalGraphPattern(
array(
new Erfurt_Sparql_Query2_Triple(
$this->getResourceVar(),
new Erfurt_Sparql_Query2_IriRef($uri),
$orderVar
)
)
);
$this->_resourceQuery->getWhere()->addElement($this->_sortTriple);
$this->_resourceQuery->getOrder()->add(
$orderVar,
$asc ? Erfurt_Sparql_Query2_OrderClause::ASC : Erfurt_Sparql_Query2_OrderClause::DESC
);
} else {
$this->_sortTriple->getElement(0)->setP(new Erfurt_Sparql_Query2_IriRef($uri));
if ($asc) {
$this->_resourceQuery->getOrder()->setAsc(0);
} else {
$this->_resourceQuery->getOrder()->setDesc(0);
}
}
$this->invalidate();
}
/**
* order by a var, that is used in the resource query
*
* @param Erfurt_Sparql_Query2_Var $var the var to order by
* @param boolean $asc true if ascending, false if descending, optional, default is true=>asc
*/
public function setOrderVar($var, $asc = true)
{
$this->setOffset(0);
if (!is_bool($asc)) {
$asc = true;
}
if ($var instanceof Erfurt_Sparql_Query2_Var) {
$this->_resourceQuery->getOrder()->setExpression(
array(
'exp' => $var,
'dir' => $asc ? Erfurt_Sparql_Query2_OrderClause::ASC : Erfurt_Sparql_Query2_OrderClause::DESC
)
);
} else {
if (is_string($var)) {
if ($var == $this->getResourceVar()->getName()) {
$this->setOrderVar($this->getResourceVar(), $asc);
}
}
}
$this->invalidate();
}
/**
* order the resources by their URI
*
* @param type $asc true if ascending, false if descending, optional, default is true=>asc
*/
public function orderByUri($asc = true)
{
$this->setOrderVar($this->getResourceVar(), $asc);
}
/**
* a legacy Method to determine the class, whose instances are shown in this list
* unfortunatley , it is not as easy as this anymore - we support other list too - then -1 is returned
*
* @deprecated since version 0.9.5
* @return string|int
*/
public static function getSelectedClass()
{
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
$listName = 'instances';
if ($listHelper->listExists($listName)) {
$list = $listHelper->getList($listName);
$filter = $list->getFilter();
return isset($filter['type0']['rdfsclass']) ? $filter['type0']['rdfsclass'] : -1;
}
return -1;
}
}
================================================
FILE: application/classes/OntoWiki/Model/Resource.php
================================================
*/
class OntoWiki_Model_Resource extends OntoWiki_Model
{
/**
* The resource URI
*
* @var string
*/
protected $_uri = null;
/**
* Array with predicate data
*
* @var array
*/
protected $_predicateResults = null;
/**
* Array with value data
*
* @var array
*/
protected $_valueResults = null;
/**
* Whether data has been fetched
*
* @var boolean
*/
protected $_queryResults = null;
/**
* Array of predicates to be ignored
*
* @var array
*/
protected $_ignoredPredicates = array();
/**
* Array of predicates to be ignored
*
* @var array
*/
protected $_limit = OW_SHOW_MAX;
/**
* Constructor
*/
public function __construct(Erfurt_Store $store, $graph, $uri, $limit = false)
{
parent::__construct($store, $graph);
$this->_uri = (string)$uri;
$this->_titleHelper = new OntoWiki_Model_TitleHelper($this->_model);
if ($limit !== false) {
$this->_limit = $limit;
}
//TODO fix query
$queryHidden = 'PREFIX sysont: SELECT ?p WHERE {?p sysont:hidden ?o }';
$res = $store->sparqlQuery($queryHidden, array("result_format" => Erfurt_Store::RESULTFORMAT_EXTENDED));
if (isset($res['bindings'])) {
$bindings = $res['bindings'];
} else {
if (isset($res['results']['bindings'])) {
$bindings = $res['results']['bindings'];
} else {
require_once 'OntoWiki/Model/Exception.php';
throw new OntoWiki_Model_Exception('invalid query result.');
}
}
foreach ($bindings as $b) {
$this->_ignoredPredicates[] = $b['p']['value'];
}
}
/**
* Returns an array of predicates and predicate infos for the current resource.
*
* @return array
*/
public function getPredicates()
{
if (null === $this->_predicateResults) {
$this->_predicateResults = array();
// get results
$results = $this->getQueryResults();
// url object to build URLs
$url = new OntoWiki_Url(array('route' => 'properties'), array('r'));
foreach ($results as $graph => $resultsForGraph) {
// set up title helper
$this->_titleHelper->addResources($resultsForGraph, 'predicate');
$this->_titleHelper->addResources($resultsForGraph, 'object');
}
foreach ($results as $graph => $resultsForGraph) {
$this->_predicateResults[$graph] = array();
foreach ($resultsForGraph as $row) {
$predicateUri = $row['predicate']['value'];
if (!array_key_exists($predicateUri, $this->_predicateResults)) {
// title
$predicateTitle = $this->_titleHelper->getTitle($predicateUri);
// url
$url->setParam('r', $predicateUri, true);
$this->_predicateResults[$graph][$predicateUri] = array(
'uri' => $predicateUri,
'curi' => OntoWiki_Utils::compactUri($predicateUri),
'url' => (string)$url,
'title' => $predicateTitle,
'has_more' => false
);
}
}
}
}
return $this->_predicateResults;
}
public function getQueryResults()
{
// query if necessary
if (null === $this->_queryResults) {
$this->_queryResults = array();
foreach ($this->_buildQueries() as $graph => $query) {
$options = array(
'result_format' => 'extended',
'use_owl_imports' => false,
'use_additional_imports' => false
);
$currentResults = $this->_store->sparqlQuery($query, $options);
if (isset($currentResults['results']['bindings'])) {
$this->_queryResults[$graph] = $currentResults['results']['bindings'];
} else {
$this->_queryResults[$graph] = array();
}
}
// remove empty results
$this->_queryResults = array_filter($this->_queryResults);
}
return $this->_queryResults;
}
/**
* Returns an array of predicate values for the current resource.
* The array is indexed with the predicate's URIs.
*
* @return array
*/
public function getValues()
{
if (null === $this->_valueResults) {
$this->_valueResults = array();
// get results
$results = $this->getQueryResults();
// load predicates first
$this->getPredicates();
// URL object to build URLs
$url = new OntoWiki_Url(array('route' => 'properties'), array('r'));
// keep track of URI objects already used
$objects = array();
foreach ($results as $graph => $resultsForGraph) {
$this->_valueResults[$graph] = array();
foreach ($resultsForGraph as $row) {
$predicateUri = $row['predicate']['value'];
if (!array_key_exists($predicateUri, $objects)) {
$objects[$predicateUri] = array();
}
// create space for value information if not exists
if (!array_key_exists($predicateUri, $this->_valueResults[$graph])) {
$this->_valueResults[$graph][$predicateUri] = array();
}
// default values
$value = array(
'content' => null,
'object' => null,
'object_hash' => null,
'datatype' => null,
'lang' => null,
'url' => null,
'uri' => null,
'curi' => null
);
switch ($row['object']['type']) {
case 'uri':
// every URI objects is only used once for each statement
if (in_array($row['object']['value'], $objects[$predicateUri])) {
continue;
}
// URL
$url->setParam('r', $row['object']['value'], true);
$value['url'] = (string)$url;
// URI
$value['uri'] = $row['object']['value'];
// title
$title = $this->_titleHelper->getTitle($row['object']['value']);
/**
* @trigger onDisplayObjectPropertyValue Triggered if an object value of some
* property is returned. Plugins can attach to this trigger in order to modify
* the value that gets displayed.
* Event payload: value, property, title and link
*/
// set up event
$event = new Erfurt_Event('onDisplayObjectPropertyValue');
$event->value = $row['object']['value'];
$event->property = $predicateUri;
$event->title = $title;
$event->link = (string)$url;
// trigger
$value['object'] = $event->trigger();
if (!$event->handled()) {
// object (modified by plug-ins)
$value['object'] = $title;
}
array_push($objects[$predicateUri], $row['object']['value']);
break;
case 'typed-literal':
$event = new Erfurt_Event('onDisplayLiteralPropertyValue');
$value['datatype'] = OntoWiki_Utils::compactUri($row['object']['datatype']);
$literalString = Erfurt_Utils::buildLiteralString(
$row['object']['value'],
$row['object']['datatype']
);
$value['object_hash'] = md5($literalString);
$event->value = $row['object']['value'];
$event->datatype = $row['object']['datatype'];
$event->property = $predicateUri;
$value['object'] = $event->trigger();
// keep unmodified value in content
$value['content'] = $row['object']['value'];
if (!$event->handled()) {
// object (modified by plug-ins)
$value['object'] = $row['object']['value'];
}
break;
case 'literal':
// original (unmodified) for RDFa
$value['content'] = $row['object']['value'];
$literalString = Erfurt_Utils::buildLiteralString(
$row['object']['value'],
null,
isset($row['object']['xml:lang']) ? $row['object']['xml:lang'] : null
);
$value['object_hash'] = md5($literalString);
/**
* @trigger onDisplayLiteralPropertyValue Triggered if a literal value of some
* property is returned. Plugins can attach to this trigger in order to modify
* the value that gets displayed.
*/
$event = new Erfurt_Event('onDisplayLiteralPropertyValue');
$event->value = $row['object']['value'];
$event->property = $predicateUri;
// set literal language
if (isset($row['object']['xml:lang'])) {
$value['lang'] = $row['object']['xml:lang'];
$event->language = $row['object']['xml:lang'];
}
// trigger
$value['object'] = $event->trigger();
// keep unmodified value in content
$value['content'] = $row['object']['value'];
// set default if event has not been handled
if (!$event->handled()) {
$value['object'] = $row['object']['value'];
}
break;
}
// push it only if it doesn't exceed number of items to display
if (count($this->_valueResults[$graph][$predicateUri]) < $this->_limit) {
array_push($this->_valueResults[$graph][$predicateUri], $value);
} else {
$this->_predicateResults[$graph][$predicateUri]['has_more'] = true;
}
if (count($this->_valueResults[$graph][$predicateUri]) > 1) {
// create the "has more link" (used for area context menu as well)
// do it only once per predicate
if (!isset($this->_predicateResults[$graph][$predicateUri]['has_more_link'])) {
//when all values are literal, we dont use a link to the list,but to the query editor
$allValuesAreLiterals = true;
foreach ($this->_valueResults[$graph][$predicateUri] as $value) {
if (isset($value['uri'])) {
$allValuesAreLiterals = false;
}
}
if (!$allValuesAreLiterals) {
$hasMoreUrl = new OntoWiki_Url(
array('route' => 'instances', 'action' => 'list'),
array()
);
$filterExp = json_encode(
array(
'filter' => array(
array(
'action' => 'add',
'mode' => 'box',
'id' => 'allvalues',
'property' => $predicateUri,
'isInverse' => true,
'propertyLabel' => "value",
'filter' => 'equals',
'value1' => $this->_uri,
'value2' => null,
'valuetype' => 'uri',
'literaltype' => null,
'hidden' => false
)
)
)
);
$hasMoreUrl->setParam(
'instancesconfig',
$filterExp
)->setParam(
'init',
true
);
} else {
$hasMoreUrl = new OntoWiki_Url(
array('controller' => 'queries', 'action' => 'editor'),
array()
);
$hasMoreUrl->setParam(
'query',
'SELECT ?value WHERE {<' . $this->_uri . '> <' . $predicateUri . '> ?value}'
)->setParam(
'immediate',
true
);
}
$this->_predicateResults[$graph][$predicateUri]['has_more_link'] = (string)$hasMoreUrl;
}
}
}
}
return $this->_valueResults;
}
}
/**
* Builds the SPARQL query
*/
private function _buildQueries()
{
$query = new Erfurt_Sparql_Query2();
$uri = new Erfurt_Sparql_Query2_IriRef($this->_uri);
$predVar = new Erfurt_Sparql_Query2_Var('predicate');
$objVar = new Erfurt_Sparql_Query2_Var('object');
$query
->addTriple($uri, $predVar, $objVar);
$query->addFilter(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_isBlank(
$objVar
)
)
);
if (!empty($this->_ignoredPredicates)) {
$or = new Erfurt_Sparql_Query2_ConditionalAndExpression();
$filter = new Erfurt_Sparql_Query2_Filter($or);
foreach ($this->_ignoredPredicates as $ignored) {
$or->addElement(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_sameTerm(
$predVar,
new Erfurt_Sparql_Query2_IriRef($ignored)
)
)
);
}
$query->getWhere()->addElement($filter);
}
$query
->setDistinct(true)
->addProjectionVar($predVar)
->addProjectionVar($objVar)
->getOrder()
->add($predVar);
$queries = array();
$closure = Erfurt_App::getInstance()->getStore()->getImportsClosure(
$this->_model->getModelUri(),
true
);
$queryGraphs = array_merge(array($this->_graph), $closure);
foreach ($queryGraphs as $currentGraph) {
$query->setFroms(array($currentGraph));
$queries[$currentGraph] = clone $query;
}
return $queries;
}
}
================================================
FILE: application/classes/OntoWiki/Model/TitleHelper.php
================================================
_model = $model;
}
$this->_erfurtApp = Erfurt_App::getInstance();
if (null !== $store) {
$this->_store = $store;
} else {
$this->_store = $this->_erfurtApp->getStore();
}
if (null == $config) {
$config = OntoWiki::getInstance()->config;
}
if (is_array($config)) {
if (isset($config['titleHelper']['properties'])) { // naming properties for resources
$this->_titleProperties = array_values($config['titleHelper']['properties']);
} else {
$this->_titleProperties = array();
}
// fetch mode
if (isset($config['titleHelper']['searchMode'])) {
$this->_alwaysSearchAllProperties = (strtolower($config['titleHelper']['searchMode']) === 'language');
}
} else {
if ($config instanceof Zend_Config) {
//its possible to define myProperties in config.ini
if (isset($config->titleHelper->myProperties)) {
$this->_titleProperties = array_values($config->titleHelper->myProperties->toArray());
} else if (isset($config->titleHelper->properties)) { // naming properties for resources
$this->_titleProperties = array_values($config->titleHelper->properties->toArray());
} else {
$this->_titleProperties = array();
}
// fetch mode
if (isset($config->titleHelper->searchMode)) {
$this->_alwaysSearchAllProperties = (strtolower($config->titleHelper->searchMode) == 'language');
}
} else {
$this->_titleProperties = array();
}
}
// always use local name for unknown resources?
if (isset($config->titleHelper->useLocalNames)) {
$this->_alwaysUseLocalNames = (bool)$config->titleHelper->useLocalNames;
}
// add localname to titleproperties
$this->_titleProperties[] = 'localname';
if (null === $this->_languages) {
$this->_languages = array();
}
if (isset($config->languages->locale)) {
array_unshift($this->_languages, (string)$config->languages->locale);
$this->_languages = array_unique($this->_languages);
}
}
// ------------------------------------------------------------------------
// --- Public methods -----------------------------------------------------
// ------------------------------------------------------------------------
/**
* Singleton instance
*
* @return OntoWiki_Model_Instance
*/
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Adds a resource to list of resources for which to query title properties.
*
* @param Erfurt_Rdf_Resource|string $resource Resource instance or URI
*
* @return OntoWiki_Model_TitleHelper
*/
public function addResource($resource)
{
$resourceUri = (string)$resource;
if (Erfurt_Uri::check($resourceUri)) {
if (empty($this->_resources[$resourceUri])) {
$this->_resources[$resourceUri] = null;
}
} else {
// throw exeption in debug mode only
if (defined('_OWDEBUG')) {
$logger = OntoWiki::getInstance()->logger;
$logger->info('Supplied resource ' . htmlentities('<' . $resource . '>') . ' is not a valid URI.');
}
}
return $this;
}
/**
* Adds a bunch of resources for which to query title properties.
* @param array $resources
* @return OntoWiki_Model_TitleHelper
*/
public function addResources($resources = array(), $variable = null)
{
if (null === $variable) {
foreach ($resources as $resourceUri) {
$this->addResource($resourceUri);
}
} else {
foreach ($resources as $row) {
foreach ((array)$variable as $key) {
if (!empty($row[$key])) {
$object = $row[$key];
$toBeAdded = null;
if (is_array($object)) {
// probably support extended format
if (isset($object['type']) && ($object['type'] == 'uri')) {
$toBeAdded = $object['value'];
}
} else {
// plain object
$toBeAdded = $object;
}
if ($toBeAdded != null) {
$this->addResource($toBeAdded);
}
}
}
}
}
return $this;
}
/**
* Returns the title property for the resource URI in the requested language.
* If no title property is found for that language the local part
* of the resource URI will be returned.
*
* @param string $resourceUri
* @param string $language The preferred language for the title
*
* @return string
*/
public function getTitle($resourceUri, $language = null)
{
if (!Erfurt_Uri::check($resourceUri)) {
return $resourceUri;
}
// * means any language
if (trim($language) == '*') {
$language = null;
}
//Have a look if we have an entry for the given resourceUri
if (!array_key_exists($resourceUri, $this->_resources) ) {
if (defined('_OWDEBUG')) {
$logger = OntoWiki::getInstance()->logger;
$logger->info('TitleHelper: getTitle called for unknown resource. Adding resource before fetch.');
}
//If we dont have an entry create one
$this->addResource($resourceUri);
}
// prepend the language that is asked for to the array
// of languages we will look for
$languages = $this->_languages;
if (null !== $language) {
array_unshift($languages, (string)$language);
}
$languages = array_values(array_unique($languages));
//Have a look if we have already a title for the given resourceUri
if ($this->_resources[$resourceUri] === null ) {
$this->_receiveTitles();
}
//Select the best found title according received titles and order of configured titleproperties
$title = $resourceUri;
$titles = $this->_resources[$resourceUri];
foreach ($languages as $language) {
foreach ($this->_titleProperties as $titleProperty) {
if (isset($titles[$titleProperty][$language]) && !empty($titles[$titleProperty][$language])) {
$title = $titles[$titleProperty][$language];
break(2);
}
}
}
return $title;
}
/**
* Add a new title property on top of the list (most important) of title properties
*
* @param $propertyUri a string with the URI of the property to add
*/
public function prependTitleProperty($propertyUri)
{
// check if we have a valid URI
if (Erfurt_Uri::check($propertyUri)) {
// remove the property from the list if it already exist
foreach ($this->_titleProperties as $key => $value) {
if ($value == $propertyUri) {
unset($this->_titleProperties[$key]);
}
}
// rewrite the array
$this->_titleProperties = array_values($this->_titleProperties);
// prepend the new URI
array_unshift($this->_titleProperties, $propertyUri);
// reset the TitleHelper to fetch resources with new title properties
$this->reset();
}
}
/**
* Resets the title helper, emptying all resources, results and queries stored
*/
public function reset()
{
$this->_resources = array();
}
/**
* operate on _resources array and call the method to fetch the titles
* if no titles found for the respective resource the localname will be extracted
*
* @return void
*/
private function _receiveTitles()
{
//first we check if there are resourceUris without a title representation
$toBeReceived = array();
foreach ($this->_resources as $resourceUri => $resource) {
if ($resource == null) {
$toBeReceived[] = $resourceUri;
}
}
//now we try to receive the Titles from ResourcePool
$this->_fetchTitlesFromResourcePool($toBeReceived);
//If we dont find titles then we extract them from LocalName
foreach ($this->_resources as $resourceUri => $resource) {
if ($resource == null) {
$this->_resources[$resourceUri]['localname']['localname']
= $this->_extractTitleFromLocalName($resourceUri);
}
}
}
/**
* fetches all titles according the given array if Uris
*
* @param array resourceUris
*/
private function _fetchTitlesFromResourcePool($resourceUris)
{
$resourcePool = $this->_erfurtApp->getResourcePool();
$resources = array();
if (!empty($this->_model)) {
$modelUri = $this->_model->getModelIri();
$resources = $resourcePool->getResources($resourceUris, $modelUri);
} else {
$resources = $resourcePool->getResources($resourceUris);
}
$memoryModel = new Erfurt_Rdf_MemoryModel();
foreach ($resources as $resourceUri => $resource) {
$resourceDescription = $resource->getDescription();
$memoryModel->addStatements($resourceDescription);
$found = false;
foreach ($this->_titleProperties as $titleProperty) {
$values = $memoryModel->getValues($resourceUri, $titleProperty);
foreach ($values as $value) {
if (!empty($value['lang'])) {
$language = $value['lang'];
} else {
$language = '';
}
$this->_resources[$resourceUri][$titleProperty][$language] = $value['value'];
}
}
}
}
/**
* extract the localname from given resourceUri
*
* @param string resourceUri
* @return string title
*/
private function _extractTitleFromLocalName($resourceUri)
{
$title = OntoWiki_Utils::contractNamespace($resourceUri);
// not even namespace found?
if ($title == $resourceUri && $this->_alwaysUseLocalNames) {
$title = OntoWiki_Utils::getUriLocalPart($resourceUri);
}
return $title;
}
}
================================================
FILE: application/classes/OntoWiki/Model.php
================================================
* @property Zend_Log $_logger
* @property Erfurt_Event_Dispatcher $_eventDispatcher
* @property Zend_Config $_config The application configuration.
*/
class OntoWiki_Model
{
/**
* The Erfurt store
*
* @var Erfurt_Store
*/
protected $_store = null;
/**
* Whether inference features are turned on
*
* @var boolean
*/
protected $_inference = true;
/**
* Model instance
*
* @var Erfurt_Rdf_Model
*/
protected $_model = null;
/**
* The current named graph URI
*
* @var string
*/
protected $_graph = null;
/**
* Constructor
*/
public function __construct(Erfurt_Store $store, Erfurt_Rdf_Model $graph)
{
// system variables
$this->_store = $store;
if (isset($this->_config->system->inference) && !(bool)$this->_config->system->inference) {
$this->_inference = false;
}
// data variables
$this->_graph = $graph->getModelIri();
$this->_model = $graph;
$this->_titleHelper = new OntoWiki_Model_TitleHelper($this->_model, $store);
$this->_titleProperties = array_flip($graph->getTitleProperties());
}
/**
* get the store that hosts this model
*
* @return Erfurt_Store
*/
public function getStore()
{
return $this->_store;
}
/**
* get the raw model/graph
*
* @return Erfurt_Rdf_Model
*/
public function getGraph()
{
return $this->_model;
}
/**
* Simulates properties that reference global objects.
*
* The globals are *not* stored as properties of this objects, otherwise
* these globals (and the whole object graph that is connected to them)
* are serialized when this object is stored in the session.
*
* @param string $name
* @return Erfurt_Event_Dispatcher|Zend_Log|Zend_Config|null
*/
public function __get($name)
{
switch ($name) {
case '_logger':
return OntoWiki::getInstance()->logger;
case '_eventDispatcher':
return Erfurt_Event_Dispatcher::getInstance();
case '_config':
return OntoWiki::getInstance()->config;
}
return null;
}
}
================================================
FILE: application/classes/OntoWiki/Module/Exception.php
================================================
*/
class OntoWiki_Module_Exception extends OntoWiki_Exception
{
}
================================================
FILE: application/classes/OntoWiki/Module/Registry.php
================================================
*/
class OntoWiki_Module_Registry
{
/**
* Default module context
*/
const DEFAULT_CONTEXT = 'Default';
const MODULE_CLASS_POSTFIX = 'Module';
const MODULE_FILE_POSTFIX = 'Module.php';
/**
* Module is open
*/
const MODULE_STATE_OPEN = 1;
/**
* Module is minimized
*/
const MODULE_STATE_MINIMIZED = 2;
/**
* Module is hidden
*/
const MODULE_STATE_HIDDEN = 3;
/**
* Array of modules
*
* @var array
*/
protected $_modules = array();
/**
* Module path
*
* @var string
*/
protected $_extensionDir = '';
/**
* Array of module states
*
* @var array
*/
protected $_moduleStates = array();
/**
* Array of module contexts (keys) and modules therein
*
* @var array
*/
protected $_moduleOrder = array();
/**
* Singleton instance
*
* @var OntoWiki_Module_Registry
*/
private static $_instance = null;
/**
* private Constructor
*/
private function __construct()
{
$this->_moduleStates = new Zend_Session_Namespace('Module_Registry');
// TODO: module order per namespace?
if (isset($this->_moduleStates->moduleOrder)) {
$this->_moduleOrder = $this->_moduleStates->moduleOrder;
}
}
/**
* Singleton instance
*
* @return OntoWiki_Module_Registry
*/
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Resets the instance to its initial state. Mainly used for
* testing purposes.
*/
public function resetInstance()
{
$this->_modules = array();
$this->_moduleStates = array();
$this->_moduleOrder = array();
}
public static function reset()
{
if (null !== self::$_instance) {
self::$_instance->resetInstance();
}
self::$_instance = null;
}
/**
* Sets the path where modules are to be found
*
* @since 0.9.5
* @return OntoWiki_Module_Registry
*/
public function setExtensionPath($extensionDir)
{
$extensionDir = (string)$extensionDir;
if (is_readable($extensionDir)) {
$this->_extensionDir = $extensionDir;
}
return $this;
}
/**
* Registers modulewith name $moduleName in namespace $namspace.
*
* @param string $extensionName the name of the extension that brings this module
* @param string $moduleName the name of the module
* @param string $context in which context the module should be shown
* @param array $options config object of the module
*
* @return OntoWiki_Module_Registry
*/
public function register($extensionName, $moduleFileName, $context = self::DEFAULT_CONTEXT, $options = null)
{
$moduleName = strtolower(
substr($moduleFileName, 0, strlen($moduleFileName) - strlen(self::MODULE_FILE_POSTFIX))
);
if (!array_key_exists($context, $this->_moduleOrder)) {
$this->_moduleOrder[$context] = array();
}
if ($options == null) {
$options = new Zend_Config(array(), true);
} else {
if (is_array($options)) {
$options = new Zend_Config($options, true);
}
}
//if not already registered
if (!array_key_exists($moduleName, $this->_modules)) {
// merge defaults
$default = new Zend_Config(
array(
'id' => strtolower($moduleName),
'classes' => '',
'name' => ucwords($moduleName),
'enabled' => true,
'extensionName' => $extensionName,
'private' => array()
),
true
);
$options = $default->merge($options);
// set css classes according to module state
if (true == property_exists($options, 'id')) {
switch ($this->_moduleStates->{$options->id}) {
case self::MODULE_STATE_OPEN:
break;
case self::MODULE_STATE_MINIMIZED:
$options->classes .= ' is-minimized';
break;
case self::MODULE_STATE_HIDDEN:
$options->classes .= ' is-disabled';
break;
}
}
// register module
$this->_modules[$moduleName] = $options;
} else {
if (in_array($moduleName, $this->_moduleOrder[$context])) {
throw new Exception("Module '$moduleName' is already registered for context '$context'.");
}
}
// set module order and context
if (isset($options->priority)) {
$position = $this->_getModulePosition($context, $options->priority);
$this->_moduleOrder[$context][$position] = $moduleName;
} else {
$this->_moduleOrder[$context][] = $moduleName;
}
return $this;
}
/**
* Returns whether the module with $moduleName has been registered
* under namespace $namespace.
*
* @param string $moduleName
* @param string $namespace
*
* @return boolean
*/
public function isModuleEnabled($moduleName)
{
return array_key_exists($moduleName, $this->_modules) && $this->_modules[$moduleName]->enabled == true;
}
/**
* Sets the module's state to disabled. If the module doesn't exists, it is
* registered as disabled.
*
* @param string $moduleName
* @param string $namespace
*
* @return OntoWiki_Module_Registry
*/
public function disableModule($moduleName, $context = self::DEFAULT_CONTEXT)
{
if ($this->isModuleEnabled($moduleName)) {
$this->_modules[$moduleName]->enabled = false;
} else {
$this->register($moduleName, $moduleName, $context, new Zend_Config(array('enabled' => false), true));
}
return $this;
}
/**
* Returns an instance of the module denoted by $moduleName, if registered.
*
* @param string $moduleName
*
* @return OntoWiki_Module
* @throws OntoWiki_Module_Exception if a module with the has not been registered.
*/
public function getModule($moduleName, $context = null)
{
if (!$this->isModuleEnabled($moduleName)) {
return null;
}
$moduleFile = $this->_extensionDir
. $this->_modules[$moduleName]->extensionName
. DIRECTORY_SEPARATOR
. ucfirst($moduleName)
. self::MODULE_FILE_POSTFIX;
if (!is_readable($moduleFile)) {
throw new OntoWiki_Module_Exception("Module '$moduleName' could not be loaded from path '$moduleFile'.");
}
// instantiate module
require_once $moduleFile;
$moduleClass = ucfirst($moduleName)
. self::MODULE_CLASS_POSTFIX;
$module = null;
if (class_exists($moduleClass)) {
$module = new $moduleClass($moduleName, $context, $this->_modules[$moduleName]);
}
return $module;
}
public function getModules()
{
return $this->_modules;
}
/**
* Returns the config for the module denoted by $moduleName.
*
* @param string $moduleName The module's name
*
* @return array
*/
public function getModuleConfig($moduleName)
{
$moduleName = (string)$moduleName;
if (array_key_exists($moduleName, $this->_modules)) {
return $this->_modules[$moduleName];
}
}
/**
* Returns all module names that are registered and enabled under
* namespace $namespace.
*
* @param string $namespace
*
* @return array|null
*/
public function getModulesForContext($context = self::DEFAULT_CONTEXT)
{
$modules = array();
if (array_key_exists($context, $this->_moduleOrder)) {
ksort($this->_moduleOrder[$context]);
foreach ($this->_moduleOrder[$context] as $moduleName) {
if (array_key_exists($moduleName, $this->_modules)) {
if ((boolean)$this->_modules[$moduleName]->enabled === true) {
$modules[$moduleName] = $this->_modules[$moduleName];
}
}
}
}
return $modules;
}
/**
* Returns the first empty position greater than $priority
* in the internal module array.
*
* @param string $context The module context
* @param int $priority The module's priority request
*/
protected function _getModulePosition($context, $priority)
{
while (array_key_exists($priority, $this->_moduleOrder[$context])) {
$priority++;
}
return $priority;
}
}
================================================
FILE: application/classes/OntoWiki/Module.php
================================================
*/
abstract class OntoWiki_Module
{
/**
* Default value for caching enabled
*
* @var boolean
*/
const MODULE_CACHING_DEFAULT = true;
/**
* OntoWiki Application config
*
* @var Zend_Config
*/
protected $_config = null;
/**
* The current module context thats loaded this module
*/
protected $_context = null;
/**
* Erfurt framework entry
*
* @var Erfurt_App
*/
protected $_erfurt = null;
/**
* Currently selected language
*
* @var string
*/
protected $_lang = null;
/**
* The module name
*
* @var string
*/
protected $_name = null;
/**
* OntoWiki Application object
*
* @var OntoWiki
*/
protected $_owApp = null;
/**
* The module private config ([private] section from module.ini file)
*
* @var Zend_Config
*/
protected $_privateConfig = null;
/**
* The module runtime options from the view's module method's second
* parameter (merged with default module options)
* injected with setOptions from the view
*
* @var Zend_Config
*/
protected $_options = null;
/**
* The current request object
*
* @var Zend_Controller_Request_Abstract
*/
protected $_request = null;
/**
* Erfurt store tab
*
* @var Erfurt_Store
*/
protected $_store = null;
/**
* File extension for template files
*
* @var string
*/
protected $_templateSuffix = 'phtml';
/**
* The module view
*
* @var Zend_View_Interface
*/
public $view = null;
/**
* Constructor
*/
public function __construct($name, $context, $config)
{
// init view
if (null === $this->view) {
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
if (null === $viewRenderer->view) {
$viewRenderer->initView();
}
$this->view = clone $viewRenderer->view;
$this->view->clearVars();
}
$this->_templateSuffix = '.' . ltrim($this->_templateSuffix, '.');
$this->_owApp = OntoWiki::getInstance();
$this->_erfurt = $this->_owApp->erfurt;
$this->_store = $this->_erfurt->getStore();
$this->_config = $this->_owApp->config;
$this->_lang = $this->_config->languages->locale;
$this->_request = Zend_Controller_Front::getInstance()->getRequest();
$this->_name = $name;
// set important script variables
$this->view->themeUrlBase = $this->_config->themeUrlBase;
$this->view->urlBase = $this->_config->urlBase;
$this->view->moduleUrl = $this->_config->staticUrlBase
. $this->_config->extensions->base
. $config->extensionName . '/';
// set the config
$this->_privateConfig = $config->private;
// set the context
$this->setContext($context);
// allow custom module initialization
$this->init();
}
/**
* Returns the current context or the default context if none has been set.
*
* @return string
*/
public function getContext()
{
if (null != $this->_context) {
return $this->_context;
}
return OntoWiki_Module_Registry::DEFAULT_CONTEXT;
}
/**
* Renders the module content with the module template.
*
* @return string
*/
public function render($template, $vars = array(), $spec = null)
{
$template = $template
. $this->_templateSuffix;
if (null === $spec) {
$this->view->assign($vars);
} else {
$this->view->assign($spec, $vars);
}
return $this->view->render($template);
}
/**
* Sets the current context so the module can perform different actions
* depending on the context.
*
* @param string $context
*/
public function setContext($context)
{
$this->_context = $context ? (string)$context : OntoWiki_Module_Registry::DEFAULT_CONTEXT;
}
/**
* Returns the rendered module.
*
* @return string
*/
public function __toString()
{
return $this->getContents();
}
/**
* Returns whether the module wants its content to be cached.
*
* The base clase implementation returns the value set in the module.ini
* config file or the default value if not set.
*
* @return boolean
*/
public function allowCaching()
{
if (isset($this->caching)) {
return (boolean)$this->caching;
}
// return default
return self::MODULE_CACHING_DEFAULT;
}
/**
* Returns wheter the module should be displayd in the current
* application state.
*
* @return boolean
*/
public function shouldShow()
{
return true;
}
/**
* Returns a string is unique to the module's state and can be used for
* cache identification.
*
* @return string
*/
public function getCacheId()
{
$id = $this->_config->host
. $this->_name
. $this->getStateId();
return $id;
}
/**
* Returns the number of seconds after which this module's content
* cache should be renewed
*
* @return int
*/
public function getCacheLivetime()
{
return 600;
}
/**
* Returns an OntoWiki_Message object that should be displayed on top of all
* module content.
*
* @return OntoWiki_Message|null
*/
public function getMessage()
{
return null;
}
/**
* Returns a string that contains the string representation
* of all variable this module's state (content) depends on.
*
* @return string
*/
public function getStateId()
{
}
/**
* Allows for custom module initialization
*/
public function init()
{
}
/**
* Returns the contents this module provides.
*
* Only provide the real content. About surrounding markup
* is taken care by OntoWiki in order to provide consistent
* look & feel.
*
* If you want to provide tabs in your module window, return
* an array whose keys are translatable names of the tabs and
* will be used as anchor ids in HTML code.
*
* @return string|array
*/
public function getContents()
{
}
/**
* Returns the title of the module
*
* If no title is provided, the title is used from the module config.
*
* @return string
*/
public function getTitle()
{
if (isset($this->title)) {
return $this->title;
}
}
/*
* setter method for options
*/
public function setOptions(Zend_Config $options = null)
{
if ($options) {
$this->_options = $options;
}
}
}
================================================
FILE: application/classes/OntoWiki/Navigation.php
================================================
*/
class OntoWiki_Navigation
{
/**
* Array with navigation elements
*
* @var array
*/
protected $_navigation = array();
/**
* Array for the default navigation element group
*
* @var array
*/
protected $_defaultGroups = array();
/**
* Array of navigation elements with configured position
*
* @var array
*/
protected $_ordered = array();
/**
* Array of navigation elements without a configured position
*
* @var array
*/
protected $_unordered = array();
/**
* Key of the currently active navigation element
*
* @var string
*/
protected $_activeKey = null;
/**
* Array of parameters that should be kept when switching navigation elements.
*
* @var array
*/
protected $_keepParams
= array(
'r'
);
/** @var boolean */
protected $_isDisabled = false;
/**
* Constructor
*/
public function __construct()
{
}
/**
* Disables the navigation for the current view.
*/
public function disableNavigation()
{
$this->_isDisabled = true;
}
/**
* Returns the currently active navigation component.
*
* @return array
*/
public function getActive()
{
if (!$this->_activeKey) {
return null;
}
return $this->_navigation[$this->_activeKey];
}
/**
* Returns whether the navigation is disabled for the current view
*
* @return boolean
*/
public function isDisabled()
{
return $this->_isDisabled;
}
/**
* Registers a component with the navigation
*
* @param string $key the identifier for the component
* @param array $options An options array for the navigation entry.
* The following keys are recognized:
* name – The name displayed on the tab
* route – A Zend route name (internal OntoWiki route;
* mapped automatically to a controller and action name
* by Zend). Controller and action keys are ignored if a
* route is given.
* controller – Controller name for the URL
* action – Action name for the URL
* priority – Priority of the tab
* @param boolean $replace Whether to replace previously registered tabs
* with the same name
*
* @todo Implement functionality to maintain a preferred order
*/
public function register($key, array $options, $replace = false)
{
if (true == array_key_exists($key, $this->_navigation) && !$replace) {
throw new OntoWiki_Exception("Navigation component with key '$key' already registered.");
}
if (!is_string($key)) {
throw new OntoWiki_Exception("Key needs to be a string.");
}
if (0 == strlen((string)$key)) {
throw new OntoWiki_Exception("No key was set.");
}
if (false == array_key_exists('name', $options)) {
$options['name'] = $key;
}
// merge defaults
$options = array_merge(
array(
'route' => null,
'controller' => null,
'action' => null,
'name' => null
), $options
);
// add registrant
$this->_navigation[$key] = $options;
// store order request
if (false == $replace) {
if (true == array_key_exists('priority', $options) && true == is_numeric($options['priority'])) {
$position = (int)$options['priority'];
while (array_key_exists((string)$position, $this->_ordered)) {
$position++;
}
$this->_ordered[$position] = $key;
} else {
$this->_unordered[] = $key;
}
}
// if this is the first element, set it active
if (1 == count($this->_navigation)) {
$this->setActive($key);
}
}
/**
* Sets the currently active navigation component.
*
* @param string $key the identifier for the component
*/
public function setActive($key)
{
if (false == array_key_exists($key, $this->_navigation)) {
throw new OntoWiki_Exception('Navigation component with key \'' . $key . '\' not registered.');
}
// set the current active to unactive
if ($this->_activeKey != null) {
unset($this->_navigation[$this->_activeKey]['active']);
}
// set new active
$this->_navigation[$key]['active'] = 'active';
// remember new
$this->_activeKey = $key;
}
/**
* Checks if a navigation components with the given key has been.
*
* @return boolean
*/
public function isRegistered($key)
{
if (array_key_exists($key, $this->_navigation)) {
return true;
}
return false;
}
/**
* Returns an array of registered navigation components
*
* @return array
*/
public function toArray()
{
if (false == $this->_isDisabled) {
$return = array();
$session = new Zend_Session_Namespace('ONTOWIKI_NAVIGATION');
if (isset($session->tabOrder)) {
$over = array_diff($this->_ordered, $session->tabOrder);
ksort($over);
$this->_ordered = array_merge($session->tabOrder, $over);
}
$request = Zend_Controller_Front::getInstance()->getRequest();
$currentController = $request->getControllerName();
$currentAction = $request->getActionName();
ksort($this->_ordered);
// first the order requests
foreach ($this->_ordered as $orderKey => $elementKey) {
if (array_key_exists($elementKey, $this->_navigation)) {
$this->_navigation[$elementKey]['url'] = $this->_getUrl(
$elementKey, $currentController, $currentAction
);
// set active if current
if ($currentController == $this->_navigation[$elementKey]['controller']
&& $currentAction == $this->_navigation[$elementKey]['action']
) {
$this->setActive($elementKey);
}
$return[$elementKey] = true;
}
}
// finally the unordered
foreach ($this->_unordered as $name => $elementKey) {
$this->_navigation[$elementKey]['url'] = $this->_getUrl(
$elementKey, $currentController, $currentAction
);
// set active if current
if ($currentController == $this->_navigation[$elementKey]['controller']
&& $currentAction == $this->_navigation[$elementKey]['action']
) {
$this->setActive($elementKey);
}
$return[$elementKey] = $this->_navigation[$elementKey];
}
// now use the most recent version from $this->_navigation, since it contains the real active state
$newReturn = array();
foreach ($return as $key => $true) {
$newReturn[$key] = $this->_navigation[$key];
}
$return = $newReturn;
return $return;
}
}
/**
* Returns the URL of the given navigation element
*
* @return OntoWiki_Url
*/
protected function _getUrl($elementKey, $currentController, $currentAction)
{
$request = Zend_Controller_Front::getInstance()->getRequest();
$router = Zend_Controller_Front::getInstance()->getRouter();
$current = $this->_navigation[$elementKey];
$hasRoute = false;
if (isset($current['route'])) {
if ($router->hasRoute($current['route'])) {
$route = $router->getRoute($current['route']);
$defaults = $route->getDefaults();
if ($defaults['controller'] == $current['controller'] && $defaults['action'] == $current['action']) {
$hasRoute = true;
}
}
}
if ($hasRoute) {
$url = new OntoWiki_Url(array('route' => $current['route']), $this->_keepParams);
} else {
$controller = $current['controller'];
$action = $current['action'] ? $current['action'] : null;
$url = new OntoWiki_Url(array('controller' => $controller, 'action' => $action), $this->_keepParams);
}
$keyBlacklist = array('route', 'controller', 'action', 'priority', 'name', 'active');
foreach ($current as $key => $value) {
if (!in_array($key, $keyBlacklist)) {
$url->setParam($key, $value);
}
}
return $url;
}
/**
*
*/
public function getNavigation()
{
return $this->_navigation;
}
/**
*
*/
public function reset()
{
$this->_navigation = array();
$this->_activeKey = null;
$this->_isDisabled = false;
$this->_defaultGroups = array();
$this->_ordered = array();
$this->_unordered = array();
$this->_keepParams = array('r');
}
}
================================================
FILE: application/classes/OntoWiki/Pager.php
================================================
*/
class OntoWiki_Pager
{
/** @var string */
public static $firstHtml = '« ';
/** @var string */
public static $prevHtml = '‹ ';
/** @var string */
public static $nextHtml = ' ›';
/** @var string */
public static $lastHtml = ' »';
/** @var array */
protected static $_options
= array(
'default_limit' => 10,
'show_first_last' => true,
'max_page_links' => 5,
'page_param' => 'p'
);
/** @var OntoWiki_Url */
protected static $_url = null;
/**
* Sets pager options statically.
*
* @param array $options
*/
public static function setOptions(array $options)
{
self::$_options = array_merge(self::$_options, $options);
}
/**
* Returns pagination links for the current URL with $count and $limit items.
*
* @param $count the total number of items
* @param $limit the number of items per page
*/
public static function get(
$count, $limit = null, $itemsOnPage = null, $page = null, $listName = null, $otherParams = array()
) {
if (null != $limit) {
self::$_options['default_limit'] = $limit;
}
if (Erfurt_Store::COUNT_NOT_SUPPORTED == $count) {
self::$_options['show_first_last'] = false;
//self::$_options['max_page_links'] = 0;
}
// get URL with params p (page number) and limit (not used atm)
$paramsToKeep = array_merge($otherParams, array('p', 'limit', 'r', 'm'));
self::$_url = new OntoWiki_Url(array(), $paramsToKeep);
self::$_url->setParam("list", $listName);
$limit = isset(self::$_url->limit) ? self::$_url->limit : self::$_options['default_limit'];
if ($limit == 0) {
// means no limit
// no pager needed
return "";
}
if (isset(self::$_url->{self::$_options['page_param']})) {
$page = self::$_url->{self::$_options['page_param']};
} else {
$page = ($page != null ? $page : 1);
}
$pagerLinks = array();
// translation helper
$translate = OntoWiki::getInstance()->translate;
// pagination necessary
if (($count > $limit) || ($count == Erfurt_Store::COUNT_NOT_SUPPORTED)) {
// previous page exists
if ($page > 1) {
if (self::$_options['show_first_last']) {
self::$_url->{self::$_options['page_param']} = 1;
self::$_url->limit = $limit;
$pagerLinks[] = sprintf(
'%s', self::$_url, self::$firstHtml . $translate->_('First')
);
}
self::$_url->{self::$_options['page_param']} = $page - 1;
self::$_url->limit = $limit;
$pagerLinks[] = sprintf(
'%s', self::$_url, self::$prevHtml . $translate->_('Previous')
);
} else {
if (self::$_options['show_first_last']) {
$pagerLinks[] = sprintf(
'%s', self::$firstHtml . $translate->_('First')
);
}
$pagerLinks[] = sprintf(
'%s', self::$prevHtml . $translate->_('Previous')
);
}
// individual page links
if ($count != null) {
if (self::$_options['show_first_last']) {
$maxLinksAsym = floor(self::$_options['max_page_links'] / 2);
$offset = 0;
} else {
// first and last links are disabled, so always show first and last individual page
$maxLinksAsym = floor((self::$_options['max_page_links'] - 2) / 2);
self::$_url->{self::$_options['page_param']} = 1;
self::$_url->limit = $limit;
if ($page == 1) {
$pagerLinks[] = '1';
} else {
$pagerLinks[] = '1';
}
$offset = 1;
// if there is a gap, show dots
if (($page - $maxLinksAsym) > 2) {
$pagerLinks[] = '…';
}
}
if ($count === Erfurt_Store::COUNT_NOT_SUPPORTED) {
for ($i = max(1 + $offset, $page - $maxLinksAsym); $i <= $page; ++$i) {
self::$_url->{self::$_options['page_param']} = $i;
self::$_url->limit = $limit;
if ($page == $i) {
$pagerLinks[] = '' . $i . '';
} else {
$pagerLinks[] = '' . $i . '';
}
}
} else {
$forLoopTest = min(ceil($count / $limit) - $offset, $page + $maxLinksAsym);
for (
$i = max(1 + $offset, $page - $maxLinksAsym); $i <= $forLoopTest; ++$i) {
self::$_url->{self::$_options['page_param']} = $i;
self::$_url->limit = $limit;
if ($page == $i) {
$pagerLinks[] = '' . $i . '';
} else {
$pagerLinks[] = '' . $i . '';
}
}
}
if (!self::$_options['show_first_last'] && ($count !== Erfurt_Store::COUNT_NOT_SUPPORTED)) {
self::$_url->{self::$_options['page_param']} = (int)ceil($count / $limit);
self::$_url->limit = $limit;
if ((self::$_url->{self::$_options['page_param']} - $page) > 2) {
$pagerLinks[] = '…';
}
if ($page == self::$_url->{self::$_options['page_param']}) {
$pagerLinks[]
= '' . self::$_url->{self::$_options['page_param']} . '';
} else {
$pagerLinks[] = ''
. self::$_url->{self::$_options['page_param']} . '';
}
}
}
// next page exists
if (($count > $page * $limit) || ($count == Erfurt_Store::COUNT_NOT_SUPPORTED && $itemsOnPage === $limit)) {
self::$_url->{self::$_options['page_param']} = $page + 1;
self::$_url->limit = $limit;
$pagerLinks[] = sprintf(
'%s', self::$_url, $translate->_('Next') . self::$nextHtml
);
if (self::$_options['show_first_last']) {
self::$_url->{self::$_options['page_param']} = (int)ceil($count / $limit);
self::$_url->limit = $limit;
$pagerLinks[] = sprintf(
'%s', self::$_url, $translate->_('Last') . self::$lastHtml
);
}
} else {
$pagerLinks[] = sprintf(
'%s', $translate->_('Next') . self::$nextHtml
);
if (self::$_options['show_first_last']) {
$pagerLinks[] = sprintf(
'%s', $translate->_('Last') . self::$lastHtml
);
}
}
$ret = '
';
foreach ($pagerLinks as $link) {
$ret .= '
' . $link . '
';
}
$ret .= '
';
return $ret;
}
}
}
================================================
FILE: application/classes/OntoWiki/Plugin.php
================================================
*/
class OntoWiki_Plugin extends Erfurt_Plugin
{
/**
* The plug-in's view for rendering templates
*
* @var OntoWiki_View
*/
public $view = null;
/**
* The plug-in URL base
*
* @var string
*/
protected $_pluginUrlBase = null;
/**
* Constructor
*/
public function __construct($root, $config = null)
{
// init view
if (null === $this->view) {
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
if (null === $viewRenderer->view) {
$viewRenderer->initView();
}
$this->view = clone $viewRenderer->view;
$this->view->clearVars();
}
$this->_pluginUrlBase = OntoWiki::getInstance()->getStaticUrlBase()
. str_replace(ONTOWIKI_ROOT, '', $root);
parent::__construct($root, $config);
}
}
================================================
FILE: application/classes/OntoWiki/Request.php
================================================
*/
class OntoWiki_Request extends Zend_Controller_Request_Http
{
/**
* Returns a parameter from the current request and expands its URI
* using the local namespace table. It also strips slashes if
* magic_quotes_gpc is turned on in PHP.
*
* @param string $name the name of the parameter
* @param boolean $expandNamespace Whether to expand the namespace or not
*
* @return mixed the parameter or null if not found
*/
public function getParam($key, $default = null, $expandNamespace = false)
{
// get parameter value from Zend_Request
$value = parent::getParam($key, $default);
if ($expandNamespace) {
// expandable parameters cannot be arrays
if (is_array($value)) {
$value = current($value);
}
// expand namespace
$value = OntoWiki_Utils::expandNamespace($value);
}
// strip slash quotes if necessary
if (get_magic_quotes_gpc() && is_string($value)) {
$value = stripslashes($value);
}
return $value;
}
}
================================================
FILE: application/classes/OntoWiki/Resource.php
================================================
*/
class OntoWiki_Resource extends Erfurt_Rdfs_Resource
{
/**
* Human-readable representation of this resource.
*/
protected $_title = null;
/**
* Title helper for CBD resources.
*
* @var OntoWiki_Model_TitleHelper
*/
protected $_descriptionHelper = null;
/**
* Returns a human-readable representation of this resource or false
* if no suitable value has been found.
*
* @return string|null
*/
public function getTitle($lang = null)
{
if (null === $this->_title) {
require_once 'OntoWiki/Model/TitleHelper.php';
$titleHelper = new OntoWiki_Model_TitleHelper($this->_model);
$titleHelper->addResource($this->getUri());
$this->_title = $titleHelper->getTitle($this->getUri(), $lang);
}
return $this->_title;
}
public function getDescriptionHelper()
{
$this->_descriptionResource($this->getUri());
return $this->_descriptionHelper;
}
protected function _descriptionResource($uri)
{
if (null === $this->_descriptionHelper) {
$this->_descriptionHelper = new OntoWiki_Model_TitleHelper($this->_model);
}
$this->_descriptionHelper->addResource($uri);
}
}
================================================
FILE: application/classes/OntoWiki/Test/ControllerTestCase.php
================================================
bootstrap = new Zend_Application(
'integration_testing',
ONTOWIKI_ROOT . 'application/config/application.ini'
);
try {
parent::setUp();
} catch (Exception $e) {
// if we can't connect to the database, we skip the test
$this->markTestSkipped($e->getMessage());
}
// additional checks for database....
$this->_markTestNeedsDatabase();
}
public function setUpUnitTest()
{
$this->bootstrap = new Zend_Application(
'unit_testing',
ONTOWIKI_ROOT . 'application/config/application.ini'
);
parent::setUp();
$this->_storeAdapter = Erfurt_App::getInstance(false)->getStore()->getBackendAdapter();
}
public function setUpExtensionUnitTest()
{
$this->bootstrap = new Zend_Application(
'extension_unit_testing',
ONTOWIKI_ROOT . 'application/config/application.ini'
);
parent::setUp();
if (null !== $this->_extensionName) {
$extensionManager = OntoWiki::getInstance()->extensionManager;
if (!$extensionManager->isExtensionActive($this->_extensionName)) {
Erfurt_Event_Dispatcher::reset();
$this->markTestSkipped('extension is not active');
}
}
$this->_ac = Erfurt_App::getInstance(false)->getAc();
$this->_storeAdapter = Erfurt_App::getInstance(false)->getStore()->getBackendAdapter();
}
public function setUpExtensionIntegrationTest()
{
$this->setUpIntegrationTest();
if (null !== $this->_extensionName) {
$extensionManager = OntoWiki::getInstance()->extensionManager;
if (!$extensionManager->isExtensionActive($this->_extensionName)) {
Erfurt_Event_Dispatcher::reset();
$this->markTestSkipped('extension is not active');
}
}
}
public function frontEndLogin() {
$store = OntoWiki::getInstance()->erfurt->getStore();
$this->request->setMethod('POST')->setPost(
array(
'u' => $store->getDbUser(),
'p' => $store->getDbPassword()
)
);
}
private function _markTestNeedsDatabase()
{
$config = Erfurt_App::getInstance(false)->getConfig();
$dbName = null;
if ($config->store->backend === 'virtuoso') {
if (isset($config->store->virtuoso->dsn)) {
$dbName = $config->store->virtuoso->dsn;
}
} else {
if ($config->store->backend === 'zenddb') {
if (isset($config->store->zenddb->dbname)) {
$dbName = $config->store->zenddb->dbname;
}
}
}
if ((null === $dbName) || (substr($dbName, -5) !== '_TEST')) {
$this->markTestSkipped('Invalid test database for tests: ' . $dbName); // make sure a test db was selected!
}
try {
$store = Erfurt_App::getInstance(false)->getStore();
$store->checkSetup();
$this->_dbWasUsed = true;
} catch (Erfurt_Store_Exception $e) {
if ($e->getCode() === 20) {
// Setup successful
$this->_dbWasUsed = true;
} else {
$this->markTestSkipped();
}
} catch (Erfurt_Exception $ee) {
$this->markTestSkipped();
}
$this->assertTrue(Erfurt_App::getInstance()->getStore()->isModelAvailable($config->sysont->modelUri, false));
$this->assertTrue(Erfurt_App::getInstance()->getStore()->isModelAvailable($config->sysont->schemaUri, false));
}
}
================================================
FILE: application/classes/OntoWiki/Test/ExtensionIntegrationTestBootstrap.php
================================================
*/
class OntoWiki_Test_ExtensionIntegrationTestBootstrap extends Bootstrap
{
}
================================================
FILE: application/classes/OntoWiki/Test/ExtensionUnitTestBootstrap.php
================================================
*/
class OntoWiki_Test_ExtensionUnitTestBootstrap extends Bootstrap
{
public function _initErfurt()
{
$erfurt = null;
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
// require OntoWiki
$this->bootstrap('OntoWiki');
$ontoWiki = $this->getResource('OntoWiki');
// require Logger, since Erfurt logger should write into OW logs dir
$this->bootstrap('Logger');
// Reset the Erfurt app for testability... needs to be refactored.
Erfurt_App::reset();
try {
$erfurt = Erfurt_App::getInstance(false)->start($config);
} catch (Erfurt_Exception $ee) {
throw new OntoWiki_Exception('Error loading Erfurt framework: ' . $ee->getMessage());
} catch (Exception $e) {
throw new OntoWiki_Exception('Unexpected error: ' . $e->getMessage());
}
$testAdapter = new Erfurt_Store_Adapter_Test();
$store = new Erfurt_Store(
array(
'adapterInstance' => $testAdapter
),
'Test'
);
$erfurt->setStore($store);
$testAc = new Erfurt_Ac_Test();
Erfurt_App::getInstance()->setAc($testAc);
// make available
$ontoWiki->erfurt = $erfurt;
return $erfurt;
}
}
================================================
FILE: application/classes/OntoWiki/Test/IntegrationTestBootstrap.php
================================================
*/
class OntoWiki_Test_IntegrationTestBootstrap extends Bootstrap
{
/**
* Overwrite the config bootstrap method, such that the store backend can be set via an environment variable.
*
* @return void|Zend_Config_Ini
*/
public function _initConfig()
{
$config = parent::_initConfig();
// Overwrite database settings from test config
// load user application configuration files
$tryDistConfig = false;
try {
$privateConfig = new Zend_Config_Ini(ONTOWIKI_ROOT . 'application/tests/config.ini', 'private', true);
$config->merge($privateConfig);
} catch (Zend_Config_Exception $e) {
$tryDistConfig = true;
}
if ($tryDistConfig === true) {
try {
$privateConfig = new Zend_Config_Ini(
ONTOWIKI_ROOT . 'application/tests/config.ini.dist', 'private', true
);
$config->merge($privateConfig);
} catch (Zend_Config_Exception $e) {
$message = 'Failed to find test config';
throw new OntoWiki_Exception($message);
}
}
// overwrite store adapter to use with environment variable if set
// this is useful, when we want to test with different stores without manually
// editing the config
if ($config instanceof Zend_Config) {
$storeAdapter = getenv('EF_STORE_ADAPTER');
if (($storeAdapter === 'virtuoso') || ($storeAdapter === 'zenddb')) {
$config->store->backend = $storeAdapter;
} else {
if ($storeAdapter !== false) {
throw new Exception('Invalid value of $EF_STORE_ADAPTER: ' . $storeAdapter);
}
}
}
return $config;
}
}
================================================
FILE: application/classes/OntoWiki/Test/UnitTestBootstrap.php
================================================
*/
class OntoWiki_Test_UnitTestBootstrap extends Bootstrap
{
public function _initExtensionManager()
{
// We do not want extensions loaded while unit testing!
return null;
}
public function _initErfurt()
{
$erfurt = null;
// require Config
$this->bootstrap('Config');
$config = $this->getResource('Config');
// require OntoWiki
$this->bootstrap('OntoWiki');
$ontoWiki = $this->getResource('OntoWiki');
// require Logger, since Erfurt logger should write into OW logs dir
$this->bootstrap('Logger');
// Reset the Erfurt app for testability... needs to be refactored.
Erfurt_App::reset();
try {
$erfurt = Erfurt_App::getInstance(false)->start($config);
} catch (Erfurt_Exception $ee) {
throw new OntoWiki_Exception('Error loading Erfurt framework: ' . $ee->getMessage());
} catch (Exception $e) {
throw new OntoWiki_Exception('Unexpected error: ' . $e->getMessage());
}
$store = new Erfurt_Store(
array(
'adapterInstance' => new Erfurt_Store_Adapter_Test()
),
'Test'
);
$erfurt->setStore($store);
$erfurt->setAc(new Erfurt_Ac_None());
// make available
$ontoWiki->erfurt = $erfurt;
return $erfurt;
}
public function _initPlugins()
{
// require front controller
$this->bootstrap('frontController');
$frontController = $this->getResource('frontController');
// We do not register any plugins for unit tests.
}
}
================================================
FILE: application/classes/OntoWiki/Toolbar.php
================================================
*/
class OntoWiki_Toolbar
{
/**
* Constants for default buttons
*/
const CANCEL = 0;
const SAVE = 1;
const EDIT = 2;
const ADD = 3;
const EDITADD = 4;
const DELETE = 5;
const EXPORT = 6;
const SUBMIT = 10;
const RESET = 11;
const SEPARATOR = 100;
/**
* Default button configurations
*
* @var array
*/
protected $_defaultButtons
= array(
self::CANCEL => array('name' => 'Cancel', 'image' => 'cancel', 'class' => 'edit cancel'),
self::SAVE => array('name' => 'Save Changes', 'image' => 'save2', 'class' => 'edit save'),
self::EDIT => array('name' => 'Edit', 'image' => 'edit', 'class' => 'edit-enable'),
self::ADD => array('name' => 'Add', 'image' => 'add'),
self::EDITADD => array('name' => 'Add', 'image' => 'editadd'),
self::DELETE => array('name' => 'Delete', 'image' => 'delete', 'class' => 'delete'),
self::SUBMIT => array('name' => 'Submit', 'class' => 'submit', 'image' => 'go2'),
self::RESET => array('name' => 'Reset', 'class' => 'reset', 'image' => 'reset'),
self::EXPORT => array('name' => 'Export', 'class' => 'export', 'image' => 'save')
);
/**
* Array of toolbar buttons
*
* @var array
*/
protected $_buttons = array();
/**
* Singleton instance
*
* @var OntoWiki_Toolbar
*/
private static $_instance = null;
/**
* Translation object
*
* @var Zend_Translate
*/
protected $_translate = null;
/**
* Constructor
*/
private function __construct()
{
}
/**
* Disallow cloning
*/
private function __clone()
{
}
/**
* Adds a button to the global toolbar.
*
* @param mixed $type either a button constant defined by OntoWiki_Toolbar or
* a name string that identifies a custom button.
* @param array $options If $type is a custom type, providing $options is mandatory.
* For default buttons $options is optional but you can overwrite the behaviour
* of default buttons by providing $options. The following keys are regognized:
* - name: the button's name
* - class: the button's css class(es)
* - id: the button's css id
* - url: the URL to be fetched when the button has been clicked.
* - title: value for the HTML title attribute (displayed as a tooltip in most browsers).
* - image: the button's theme image name (w/o icon- and .png, eg. 'edit' for 'icon-edit.png')
* - image_url: the complete URL of the button's image. Use this to define custom images that are
* stored anywhere on the web.
*
* @return OntoWiki_Toolbar
*/
public function appendButton($type, array $options = array())
{
if ($button = $this->_getButton($type, $options)) {
array_push($this->_buttons, $button);
}
return $this;
}
/**
* Returns an instance of OntoWiki_Toolbar
*
* @return OntoWiki_Toolbar
*/
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Adds a button to the front of the global toolbar.
*
* @param mixed $type either a button constant defined by OntoWiki_Toolbar or
* a name string that identifies a custom button.
* @param array $options If $type is a custom type, providing $options is mandatory.
* For default buttons $options is optional but you can overwrite the behaviour
* of default buttons by providing $options. The following keys are regognized:
* - name: the button's name
* - class: the button's css class(es)
* - id: the button's css id
* - url: the URL to be fetched when the button has been clicked.
* - title: value for the HTML title attribute (displayed as a tooltip in most browsers).
* - image: the button's theme image name (w/o icon- and .png, eg. 'edit' for 'icon-edit.png')
* - image_url: the complete URL of the button's image. Use this to define custom images that are
* stored anywhere on the web.
*
* @return OntoWiki_Toolbar
*/
public function prependButton($type, array $options = array())
{
if ($button = $this->_getButton($type, $options)) {
array_unshift($this->_buttons, $button);
}
return $this;
}
/**
* Sets the URL base for the current theme
*
* @since 0.9.5
*
* @param string $themeUrlBase The URL base into the theme dir
*
* @return OntoWiki_Toolbar
*/
public function setThemeUrlBase($themeUrlBase)
{
$this->_themeUrlBase = (string)$themeUrlBase;
return $this;
}
/**
* Sets the translation object for the current UI language
*
* @since 0.9.5
*
* @param Zend_Translate $translate The translation object
*
* @return OntoWiki_Toolbar
*/
public function setTranslate(Zend_Translate $translate)
{
$this->_translate = $translate;
return $this;
}
/**
* Renders the toolbar as an HTML string.
*
* @return string
*/
public function __toString()
{
return '
' . implode('', $this->_buttons) . '
';
}
/**
* Returns HTML for the specified button type.
*
* @param int $type the button type
* @param array $options button options
*
* @return string
*/
private function _getButton($type, $options = array())
{
if ($type == self::SEPARATOR) {
return '';
} else {
if (array_key_exists($type, $this->_defaultButtons)) {
$options = array_merge($this->_defaultButtons[$type], $options);
} else {
if (empty($options)) {
throw new OntoWiki_Exception("Missing options for button '$type'.");
}
if (!array_key_exists('name', $options)) {
$options['name'] = $type;
}
}
}
// translate name
if (array_key_exists('name', $options)) {
if ($this->_translate instanceof Zend_Translate) {
$label = $this->_translate->translate($options['name']);
} else {
$label = $options['name'];
}
} else {
$label = null;
}
// set class
if (array_key_exists('+class', $options)) {
$addedClasses = $options['+class'];
}
// set class
if (array_key_exists('class', $options)) {
$class = $options['class'];
if (isset($addedClasses)) {
$class = $class
. ' '
. $addedClasses;
}
} else {
if (isset($addedClasses)) {
$class = $addedClasses;
} else {
$class = null;
}
}
// set id
if (array_key_exists('id', $options)) {
$id = 'id="' . $options['id'] . '"';
} else {
$id = null;
}
if (array_key_exists('url', $options)) {
$href = 'href="' . $options['url'] . '"';
} else {
$href = null;
}
if (array_key_exists('title', $options)) {
$title = 'title="' . $options['title'] . '"';
} else {
$title = null;
}
if (array_key_exists('attributes', $options) && is_array($options['attributes'])) {
$attributes = array();
foreach ($options['attributes'] as $key => $value) {
$attributes[] = $key . '="' . $value . '"';
}
$attributes = implode(' ', $attributes);
} else {
$attributes = null;
}
// set image
if (array_key_exists('image_url', $options)) {
$image = $options['image_url'];
} else {
if (array_key_exists('image', $options)) {
$image = $this->_themeUrlBase . 'images/icon-' . $options['image'] . '.png';
} else {
$image = null;
}
}
// construct button link
$button = sprintf(
' %s',
$class,
$id,
$href,
$title,
$attributes,
$image,
$label
);
return $button;
}
}
================================================
FILE: application/classes/OntoWiki/Url.php
================================================
*/
class OntoWiki_Url
{
/**
* The current request object
*
* @var Zend_Controller_Request_Abstract
*/
protected $_request = null;
/**
* Array of URL parameters
*
* @var array
*/
protected $_params = null;
/**
* Controller name for the URL
*
* @var string
*/
protected $_controller = null;
/**
* Action name for the URL
*
* @var string
*/
protected $_action = null;
/**
* Router used for the current request
*
* @var Zend_Controller_Router_Route
*/
protected $_route = null;
/**
* Whether to use nice search-engine friendly URLs
*
* @var boolean
*/
protected $_useSefUrls = true;
/**
*
*/
protected $_base = null;
/**
* Constructor
*/
public function __construct(array $options = array(), $paramsToKeep = null, $paramsToExclude = null, $base = null)
{
$this->_request = Zend_Controller_Front::getInstance()->getRequest();
$defaultAction = Zend_Controller_Front::getInstance()->getDefaultAction();
$defaultController = Zend_Controller_Front::getInstance()->getDefaultControllerName();
$router = Zend_Controller_Front::getInstance()->getRouter();
// use defaults - current page
if (!isset($options['route']) && !isset($options['controller']) && !isset($options['action'])) {
$options['controller'] = $this->_request->getControllerName();
$options['action'] = $this->_request->getActionName();
}
if ($base != null && is_string($base)) {
$this->_base = $base;
} else {
if (isset(OntoWiki::getInstance()->config->urlBase)) {
$this->_base = OntoWiki::getInstance()->config->urlBase;
} else {
$this->_base = "http://ns.aksw.org/undefined/";
}
}
// keep parameters
if (!$this->_request) {
$this->_params = array();
} else {
if (is_array($paramsToKeep)) {
$this->_params = array_intersect_key($this->_request->getParams(), array_flip($paramsToKeep));
} else {
$this->_params = $this->_request->getParams();
}
}
if (is_array($paramsToExclude)) {
foreach ($paramsToExclude as $param) {
if (isset($this->_params[$param])) {
unset($this->_params[$param]);
}
}
}
// set route
$flag = false;
if (array_key_exists('route', $options) && $router->hasRoute($options['route'])) {
$flag = true;
$this->_route = $router->getRoute($options['route']);
} else {
// set controller
if (array_key_exists('controller', $options) && $options['controller']) {
$flag = true;
$this->_controller = rtrim($options['controller'], '/');
} else {
if (array_key_exists('controller', $this->_params) && $this->_params['controller']) {
$this->_controller = $this->_params['controller'];
}
}
// set action
if (array_key_exists('action', $options) && $options['action']) {
$flag = true;
$this->_action = rtrim($options['action'], '/');
} else {
if (array_key_exists('action', $this->_params) && $this->_params['action']) {
$this->_action = $this->_params['action'];
}
}
}
if (!$flag) {
try {
$routeName = $router->getCurrentRouteName();
} catch (Exception $e) {
$routeName = 'default';
}
if ($router->hasRoute($routeName)) {
$this->_route = $router->getRoute($routeName);
}
}
// check default controller/action and leave those empty
if (rtrim($this->_action, '/') == $defaultAction) {
$this->_action = '';
if (rtrim($this->_controller, '/') == $defaultController) {
$this->_controller = '';
}
}
// don't need these anymore
unset($this->_params['module']);
unset($this->_params['controller']);
unset($this->_params['action']);
}
/**
* set base url (for unittests)
*
* @param string $base
*/
public function setBase($base)
{
$this->_base = $base;
}
/**
* Returns a URL string representing the object
*
* @return string
*/
public function __toString()
{
try {
return $this->_buildQuery();
} catch (Exception $e) {
echo $e;
return '';
}
}
/**
* Returns the URL parameters
*
* @return array
*/
public function getParams()
{
return $this->_params;
}
/**
* Sets a URL parameter. Paramters with the same name already
* set will be overwritten.
*
* @param string $name parameter name
* @param string $value parameter value
* @param boolean $contractNamespace denotes whether to contract namespaces in URIs
*
* @return OntoWiki_Url
*/
public function setParam($name, $value, $contractNamespace = false)
{
switch ($name) {
case 'controller':
case 'action':
$this->{'_' . $name} = $value;
break;
default:
if (null !== $value) {
if ($contractNamespace) {
$value = OntoWiki_Utils::contractNamespace($value);
}
$this->_params[$name] = $value;
} else {
unset($this->_params[$name]);
}
}
// allow chaining
return $this;
}
/**
* Sets a URL parameter. Paramters with the same name already
* set will be overwritten.
*
* @param string $name parameter name
* @param string $value parameter value
*
* @return OntoWiki_Url
*/
public function __set($name, $value)
{
return $this->setParam($name, $value);
}
/**
* Returns the value of parameter $name
*
* @param string $name parameter name
*
* @return string the value of parameter $name
*/
public function __get($name)
{
if (isset($this->_params[$name])) {
return $this->_params[$name];
}
}
/**
* Returns whether parameter $name is set
*
* @param string $name parameter name
*
* @return boolean
*/
public function __isset($name)
{
return isset($this->_params[$name]);
}
/**
* Unsets the parameter $name
*
* @param string $name parameter name
*
* @return OntoWiki_Url
*/
public function __unset($name)
{
if (isset($this->$this->_params[$name])) {
unset($this->$this->_params[$name]);
}
// allow chaining
return $this;
}
/**
* Builds the query part of the URL
*/
protected function _buildQuery()
{
$event = new Erfurt_Event('onBuildUrl');
$event->base = $this->_base;
$event->route = $this->_route;
$event->controller = $this->_controller;
$event->action = $this->_action;
$event->params = $this->_params;
$urlCreated = $event->trigger();
if ($event->handled()) {
if ($urlCreated && isset($event->url)) {
return $event->url;
} else {
$this->_params = $event->params;
$this->_controller = $event->controller;
$this->_action = $event->action;
$this->_route = $event->route;
}
}
// check params
foreach ($this->_params as $name => $value) {
if (is_string($value) && preg_match('/\//', $value)) {
$this->_useSefUrls = false;
}
}
$url = '';
if ($this->_route) {
// checking if reset of route-defaults necessary
// fixes pager usage fails on versioning pages
if (count($this->_route->getDefaults()) == 0) {
$resetRoute = false;
} else {
$resetRoute = true;
}
if ($this->_useSefUrls) {
// let the route assemble the whole URL
$url = $this->_route->assemble($this->_params, $resetRoute, true);
} else {
// we will assign parameters ourselves
$url = $this->_route->assemble(array(), $resetRoute);
$url = sprintf('%s/%s', $url, '?' . http_build_query($this->_params, '&'));
}
} else {
if ($this->_useSefUrls) {
$query = '';
$lastKey = '';
foreach ($this->_params as $key => $value) {
if (is_scalar($value)) {
$value = urlencode($value);
$query .= "$key/$value/";
$lastKey = $key;
}
}
// remove trailing slash
$query = rtrim($query, '/');
} else {
$query = '?' . http_build_query($this->_params, '&');
}
$parts = array_filter(array($this->_controller, $this->_action, $query));
$url = implode('/', $parts);
}
// HACK:
$this->_useSefUrls = true;
return $this->_base . ltrim($url, '/');
}
}
================================================
FILE: application/classes/OntoWiki/Utils/Exception.php
================================================
*/
class OntoWiki_Utils_Exception extends OntoWiki_Exception
{
}
================================================
FILE: application/classes/OntoWiki/Utils.php
================================================
*/
class OntoWiki_Utils
{
/**
* Pseudo-prefix for the current graph
*/
const DEFAULT_BASE = '__default';
/**
* Separator between namespace prefix and local part
*/
const PREFIX_SEPARATOR = ':';
/**
* An array of namespace prefixes and IRIs.
*
* @var array
*/
private static $_namespaces = null;
/**
* Returns a compact URI (cURI) as required by RDFa syntax specification
* {@link http://www.w3.org/MarkUp/2008/ED-rdfa-syntax-20080125/#s_curieprocessing}.
* Adds an ad-hoc namespace prefix if it cannot find one for the URI, resulting
* in a value that is guaranteed to be a cURI.
*
* @param string $uri the URI to be converted
*
* @return string|null cURI or null if no cURI could be created
*/
public static function compactUri($uri, $saveMode = false)
{
$namespaces = self::_getNamespaces();
$selectedModel = OntoWiki::getInstance()->selectedModel;
$compactUri = null;
$prefix = null;
// split URI in namespace and local part at "/", "#" or ":"
$matches = array();
preg_match('/^(.+[#\/\:])(.+[^#\/\:])$/', $uri, $matches);
if (count($matches) == 3) {
$namespace = $matches[1];
$localPart = $matches[2];
if (!empty($localPart) && $selectedModel) {
try {
$prefix = $selectedModel->getNamespacePrefix($namespace);
} catch (Erfurt_Exception $e) {
// just to be save
$prefix = null;
}
}
}
// usable prefix found?
if (null !== $prefix) {
$compactUri = $prefix
. self::PREFIX_SEPARATOR
. $localPart;
} else {
if ($saveMode) {
throw new OntoWiki_Utils_Exception("Unable to compact URI <$uri>.");
} else {
// return URI unmodified
$compactUri = $uri;
}
}
return $compactUri;
}
/**
* Replaces a namespace URI with its prefix if found in the local
* prefix table.
*
* @deprecated Use compactUri instead
*
* @param string $uri The URI
* @param boolean $prependBase Whether to prepend the graph base URI
*
* @return string
*/
public static function contractNamespace($uri, $prependBase = false)
{
$namespaces = self::_getNamespaces();
$matches = array();
preg_match('/^(.+[#\/])(.+[^#\/])$/', $uri, $matches);
$matchesCount = count($matches);
if ($matchesCount >= 3) {
$selectedModel = OntoWiki::getInstance()->selectedModel;
if ($selectedModel && $matches[1] == $selectedModel->getBaseIri()) {
if ($prependBase) {
return self::DEFAULT_BASE . ':' . $matches[2];
}
return $matches[2];
} else {
if (array_key_exists($matches[1], $namespaces)) {
return $namespaces[$matches[1]] . ':' . $matches[2];
}
}
}
return $uri;
}
/**
* Calculates the Difference between two timestamps
*
* @param string/int $startTimestamp
* @param integer $endTimestamp
* @param integer $unit (default 0)
*
* @return string
*/
public static function dateDifference($startTimestamp, $endTimestamp = false, $unit = 0)
{
$translate = OntoWiki::getInstance()->translate;
$starDaySeconds = (23 * 56 * 60) + 4.091; // Star Day
$sunDaySeconds = 24 * 60 * 60; // Sun Day
if ($unit == 0) {
$dayInSeconds = $sunDaySeconds;
} else {
$dayInSeconds = $starDaySeconds;
}
if (is_int($startTimestamp)) {
if ($endTimestamp) {
$differenceInSeconds = $endTimestamp - $startTimestamp;
} else {
$endTimestamp = time();
$differenceInSeconds = $endTimestamp - $startTimestamp;
}
} else {
if (is_string($startTimestamp)) {
if ($endTimestamp) {
if ($t = strtotime($startTimestamp)) {
$differenceInSeconds = $endTimestamp - $t;
} else {
throw new Exception('unexpected format of timestamp.');
}
} else {
$endTimestamp = time();
if ($t = strtotime($startTimestamp)) {
$differenceInSeconds = $endTimestamp - $t;
} else {
throw new Exception('unexpected format of timestamp.');
}
}
} else {
throw new Exception(
'unexpected type of timestamp. ' .
'expected string (date) or int (timestamp), got ' .
gettype($startTimestamp) . ' instead'
);
}
}
//if start is in the past, we use negative differences
$differenceInSeconds *= -1;
// show e.g. 'moments ago' if time is less than one minute
if (abs($differenceInSeconds) < 60) {
if ($differenceInSeconds < 0) {
return $translate->_('moments ago');
} else {
return $translate->_('in moments');
}
} else {
$differenceInMinutes = round(($differenceInSeconds / 60));
// show e.g. 'approx. x minutes ago' if time is less than one hour
if (abs($differenceInMinutes) == 1) {
if ($differenceInSeconds < 0) {
return $translate->_('approx. 1 minute ago');
} else {
return $translate->_('in approx. 1 minute');
}
} else {
if (abs($differenceInMinutes) < 60) {
if ($differenceInMinutes < 0) {
return sprintf($translate->_('approx. %d minutes ago'), abs($differenceInMinutes));
} else {
return sprintf($translate->_('in approx. %d minutes'), abs($differenceInMinutes));
}
} else {
$differenceInHours = round(($differenceInSeconds / 3600));
// show e.g. 'approx. x hours
if (abs($differenceInHours) == 1) {
if ($differenceInHours < 0) {
return $translate->_('approx. 1 hour ago');
} else {
return $translate->_('in approx. 1 hour');
}
} else {
if (abs($differenceInHours) <= 48) {
if ($differenceInHours < 0) {
return sprintf($translate->_('approx. %d hours ago'), abs($differenceInHours));
} else {
return sprintf($translate->_('in approx. %d hours'), abs($differenceInHours));
}
} else {
$differenceInDays = round(($differenceInSeconds / $dayInSeconds));
// else return e.g. 'approx. x days ago'
if ($differenceInDays < 0) {
return sprintf($translate->_('approx. %d days ago'), abs($differenceInDays));
} else {
return sprintf($translate->_('in approx. %d days'), abs($differenceInDays));
}
}
}
}
}
}
}
/**
* Expands a namespace prefix in a quialified name to a full URI if found
* in the local namespace table.
*
* @param string $qName The qualified name, e.g. 'foaf:Person'
*
* @return string
*/
public static function expandNamespace($qName)
{
$namespaces = self::_getNamespaces();
if (trim($qName) != '') {
$parts = explode(':', $qName);
$namespaces = array_flip($namespaces);
$prefix = isset($parts[0]) ? $parts[0] : '';
$localPart = isset($parts[1]) ? $parts[1] : '';
if (array_key_exists($prefix, $namespaces) && !empty($localPart)) {
$qName = $namespaces[$prefix];
array_shift($parts);
$qName .= implode('', $parts);
} else {
// TODO: check store, better URI check, use model base URI
$owApp = OntoWiki::getInstance();
$erfurtConfig = Erfurt_App::getInstance()->getConfig();
$uriSchemas = array_flip($erfurtConfig->uri->schemata->toArray());
if (array_key_exists($prefix, (array)$uriSchemas)) {
// prefix is an allowed URI schema
return $qName;
} else {
if ($owApp->selectedModel instanceof Erfurt_Rdf_Model) {
$qName = $owApp->selectedModel->getBaseIri() . $qName;
}
}
}
return $qName;
}
}
/**
* Returns the local part of a URI.
*
* @param string $uri
*
* @return string
*/
public static function getUriLocalPart($uri)
{
$namespaces = self::_getNamespaces();
$localPart = $uri;
$matches = array();
preg_match('/^(.+[#\/])(.+[^#\/])$/', $uri, $matches);
if (count($matches) == 3) {
if (trim($matches[2]) != '') {
$localPart = $matches[2];
}
}
return $localPart;
}
/**
* Matches an array of mime types against the Accept header in a request.
*
* @param Zend_Controller_Request_Abstract $request the request
* @param array $supportedMimetypes The mime types to match against
*
* @return string
*/
public static function matchMimetypeFromRequest(
Zend_Controller_Request_Http $request,
array $supportedMimetypes
) {
// get accept header
$acceptHeader = strtolower($request->getHeader('Accept'));
try {
$match = \Bitworking\Mimeparse::bestMatch($supportedMimetypes, $acceptHeader);
} catch (Exception $e) {
$match = '';
}
return $match;
}
/**
* Shortens a string by splitting it in the middle and concatenating
* both parts with an ellipse (…)
*
* @param string $string The string to be split
* @param int $maxLength The maximum length of the resulting string
*
* @return string
*/
public static function shorten($string, $maxLength = 20)
{
if (($maxLength == 0) || (strlen($string) < $maxLength)) {
return $string;
}
$offset = floor($maxLength / 2);
$short = rtrim(substr($string, 0, $offset), '.')
. '…'
. ltrim(substr($string, -$offset, $offset), '.');
return $short;
}
/**
* Loads the namespaces from the currently selected model
*/
private static function _reloadNamespaces()
{
$model = OntoWiki::getInstance()->selectedModel;
if ($model instanceof Erfurt_Rdfs_Model) {
self::$_namespaces = $model->getNamespaces();
} else {
self::$_namespaces = array();
}
}
/**
* Loads the local namespace table from the currently active graph.
*
* @return array
*/
private static function _getNamespaces()
{
if (null === self::$_namespaces) {
self::_reloadNamespaces();
}
return self::$_namespaces;
}
static public function array_to_object(array $array)
{
// Iterate through our array looking for array values.
// If found recurvisely call itself.
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = self::array_to_object($value);
}
}
// Typecast to (object) will automatically convert array -> stdClass
return (object)$array;
}
static public function object_to_array(object $array)
{
// Iterate through our array looking for array values.
// If found recurvisely call itself.
foreach ($array as $key => $value) {
if (is_array($value)) {
$array[$key] = self::object_to_array($value);
}
}
// Typecast to (object) will automatically convert array -> stdClass
return (array)$array;
}
static public function object_merge_recursive($a, $b)
{
return self::array_to_object(
array_merge_recursive(
self::object_to_array($a),
self::object_to_array($b)
)
);
}
/**
* cast an object to the most general class.
* also makes implicit (__get-magic) properties explicit
*
* @param type $o
*/
static public function to_stdclass_recursive($o)
{
$ret = new stdClass();
foreach ($o as $k => $v) {
if (is_object($v) && get_class($v) != 'stdClass') {
$v = self::to_stdclass_recursive($v);
}
$ret->{$k} = $v;
}
return $ret;
}
}
================================================
FILE: application/classes/OntoWiki/View/Helper/Curie.php
================================================
*/
class OntoWiki_View_Helper_Curie extends Zend_View_Helper_Abstract
{
public function curie($uri)
{
$curi = OntoWiki_Utils::compactUri($uri);
return $curi;
}
}
================================================
FILE: application/classes/OntoWiki/View.php
================================================
*/
class OntoWiki_View extends Zend_View
{
/**
* OntoWiki application config
*
* @var Zend_Config
*/
protected $_config = null;
/**
* The user interface language currently set
*
* @var string
*/
protected $_lang = null;
/**
* Module cache
*
* @var Zend_Cache
*/
protected $_moduleCache = null;
/**
* Translation object
*
* @var Zend_Translate
*/
protected $_translate = null;
/**
* Zend View Placeholder registry
*
* @var Zend_View_Helper_Placeholder_Registry
*/
protected $_placeholderRegistry = null;
/**
* Subview for rendering modules
*
* @var OntoWiki_View
*/
protected $_moduleView = null;
/**
* Constructor
*/
public function __construct($config = array(), $translate = null)
{
parent::__construct($config);
$this->_config = OntoWiki::getInstance()->config;
$this->_translate = $translate;
$this->_placeholderRegistry = Zend_View_Helper_Placeholder_Registry::getRegistry();
if (array_key_exists('use_module_cache', $config) && (boolean)$config['use_module_cache']) {
$this->_moduleCache = OntoWiki::getInstance()->getCache();
}
}
/**
* Provides a shortcut to Zend_Translate from within templates.
*
* Also tries to cast to string.
*
* @param string $key the key for the translation table
*/
public function _($key)
{
return $this->_translate->translate((string)$key);
}
/**
* Checks whether a placeholder contains data or view variable exists
*
* @param string $name the name of the placeholder or view variable
*/
public function has($name)
{
// check view variables
if (isset($this->$name) && !empty($this->$name) && $this->$name != '') {
return true;
}
// check placeholders
if ($this->_placeholderRegistry->containerExists($name)) {
$value = $this->_placeholderRegistry->getContainer($name)->getValue();
if (is_array($value)) {
foreach ($value as $v) {
if (!empty($v) && ($v != '')) {
return true;
}
}
} else {
if (!empty($value) && ($value != '')) {
return true;
}
}
}
return false;
}
/**
* Clears the cache entry for a specific module or all modules.
*
* @param string|null $moduleName If null, all cache for all modules is cleared.
*
* @return bool
*/
public function clearModuleCache($moduleName = null)
{
if ($this->_moduleCache) {
if (null !== $moduleName) {
return $this->_moduleCache->clean(Zend_Cache::CLEANING_MODE_MATCHING_TAG, array('module', $moduleName));
}
return $this->_moduleCache->clean(Zend_Cache::CLEANING_MODE_ALL);
}
}
/**
* Renders all modules registered for a certain module context.
*
* @param string $context The module context whose modules should be rendered
*
* @return string
*/
public function modules($context, $renderOptions = null)
{
$modules = '';
foreach (OntoWiki_Module_Registry::getInstance()->getModulesForContext($context) as $moduleSpec) {
$modules .= $this->module($moduleSpec->id, $renderOptions, $context);
}
return $modules;
}
/**
* Module view helper.
*
* Returns an OntoWiki module either rendered or from cache.
*
* Fetches the module from the module registry and renders it into the
* window template. If a rendering exists in the local module cache it
* is used instead.
*
* @param string $moduleName
* @param array $moduleOptions An associative array or and instance of
* Zend_config with module options.
* The following keys can be used:
* enabled – whether the module is enabled or disabled
* title – the module window's title
* caching – whether the module should be cached
* priority – priority of the module in the module contexts
* lower number means higher priority
* classes – string of css classes for the module window
* id – a css id for the module window
*
* @return string
*/
public function module($moduleName, $renderOptions = null, $context = OntoWiki_Module_Registry::DEFAULT_CONTEXT)
{
$moduleRegistry = OntoWiki_Module_Registry::getInstance();
// allow old-style array config
if (is_array($renderOptions)) {
$renderOptions = new Zend_Config($renderOptions);
}
// get default options from the registry
$defaultModuleOptions = $moduleRegistry->getModuleConfig($moduleName);
if ($defaultModuleOptions == null) {
$moduleOptions = $renderOptions;
} else {
if ($renderOptions != null) {
$moduleOptions = $defaultModuleOptions->merge($renderOptions);
} else {
$moduleOptions = $defaultModuleOptions;
}
}
$cssClasses = isset($moduleOptions->classes) ? $moduleOptions->classes : '';
$cssId = isset($moduleOptions->id) ? $moduleOptions->id : '';
$module = $moduleRegistry->getModule($moduleName, $context);
// no module found
if (null == $module) {
return '';
}
$module->setOptions($moduleOptions);
if ($module->shouldShow()) {
// init module view
if (null == $this->_moduleView) {
$this->_moduleView = clone $this;
}
$this->_moduleView->clearVars();
// query module's title
$this->_moduleView->title = $module->getTitle();
// does the module have a message
// TODO: allow multiple messages
if (method_exists($module, 'getMessage')) {
if ($message = $module->getMessage()) {
$this->_moduleView->messages = array($message);
}
}
// does the module have a menu?
if (method_exists($module, 'getMenu')) {
$menu = $module->getMenu();
$this->_moduleView->menu = $menu->toArray(false, false);
}
// does the module have a context menu?
if (method_exists($module, 'getContextMenu')) {
$contextMenu = $module->getContextMenu();
if ($contextMenu instanceof OntoWiki_Menu) {
$contextMenu = $contextMenu->toArray();
}
$this->_moduleView->contextmenu = $contextMenu;
}
// is caching enabled
if ($this->_moduleCache && $module->allowCaching()) {
// get cache id
$cacheId = md5($module->getCacheId() . $cssClasses . $this->_config->languages->locale);
// cache hit?
if (!$moduleContent = $this->_moduleCache->load($cacheId)) {
// render (expensive) contents
$pre = microtime(true);
$moduleContent = $module->getContents();
$post = ((microtime(true) - $pre) * 1000);
// save to cache
$this->_moduleCache->save(
$moduleContent, $cacheId, array('module', $moduleName), $module->getCacheLivetime()
);
}
} else {
// caching disabled
$pre = microtime(true);
$moduleContent = $module->getContents();
$post = ((microtime(true) - $pre) * 1000);
}
// implement tabs
if (is_array($moduleContent)) {
// TODO: tabs
$navigation = array();
$content = array();
$i = 0;
foreach ($moduleContent as $key => $content) {
$navigation[$key] = array(
'active' => $i++ == 0 ? 'active' : '',
'url' => '#' . $key,
'name' => $this->_($key)
);
}
$this->_moduleView->navigation = $navigation;
$this->_moduleView->content = $moduleContent;
} else {
if (is_string($moduleContent)) {
$this->_moduleView->content = $moduleContent;
}
}
// set variables
$this->_moduleView->cssClasses = $cssClasses;
$this->_moduleView->cssId = $cssId;
if (isset($moduleOptions->noChrome) && (boolean)$moduleOptions->noChrome) {
// render without window chrome
$moduleWindow = $this->_moduleView->render('partials/module.phtml');
} else {
// render with window chrome
$moduleWindow = $this->_moduleView->render('partials/window.phtml');
}
return $moduleWindow;
}
}
}
================================================
FILE: application/classes/OntoWiki.php
================================================
*/
class OntoWiki
{
const DEFAULT_LOG_IDENTIFIER = 'ontowiki';
// ------------------------------------------------------------------------
// --- Properties
// ------------------------------------------------------------------------
/**
* The bootstrap object used during bootstrap.
*
* @var Zend_Application_Bootstrap_Bootstrap
*/
protected $_bootstrap = null;
/**
* A dictionary for custom logger objects.
* The key is the identifier for the logger.
*/
protected $_customLogs = array();
/**
* Array of properties
*
* @var array
*/
protected $_properties = array();
/**
* Variables to be autoloaded from the session
*
* @var array
*/
protected $_sessionVars = array();
/**
* Singleton instance
*
* @var OntoWiki
*/
protected static $_instance = null;
/**
* OntoWiki_Navigation instance
*/
protected $_navigation = null;
// ------------------------------------------------------------------------
// --- Magic Methods
// ------------------------------------------------------------------------
/**
* Constructor
*/
private function __construct()
{
}
/**
* Disallow cloning
*/
private function __clone()
{
}
/**
* Returns a property value
*
* @param string $propertyName
*
* @return mixed
* @since 0.9.5
*/
public function __get($propertyName)
{
// retrieve from session
if (in_array($propertyName, $this->_sessionVars)) {
if (isset($this->session->$propertyName)) {
$this->_properties[$propertyName] = $this->session->$propertyName;
}
}
// retrieve bootstrap resource
$bootstrap = $this->getBootstrap();
if ($bootstrap && $bootstrap->hasResource($propertyName)) {
return $bootstrap->getResource($propertyName);
}
// retrieve locally
if (isset($this->$propertyName)) {
return $this->_properties[$propertyName];
}
}
/**
* Sets a property
*
* @param string $propertyName
* @param mixed $propertyValue
*
* @since 0.9.5
*/
public function __set($propertyName, $propertyValue)
{
// set in session
if (in_array($propertyName, $this->_sessionVars)) {
$this->session->$propertyName = $propertyValue;
}
// set locally
$this->_properties[$propertyName] = $propertyValue;
}
/**
* Returns whether a property is set
*
* @param string $propertyName
*
* @return boolean
* @since 0.9.5
*/
public function __isset($propertyName)
{
return array_key_exists($propertyName, $this->_properties);
}
/**
* Unsets a property
*
* @param string $propertyName
*
* @since 0.9.5
*/
public function __unset($propertyName)
{
// unset from session
if (in_array($propertyName, $this->_sessionVars)) {
unset($this->session->$propertyName);
}
// unset locally
unset($this->_properties[$propertyName]);
}
// ------------------------------------------------------------------------
// --- Public Methods
// ------------------------------------------------------------------------
/**
* Appends a (translated) message to the message stack
* TODO: add a boolean $translate=true flag in order to allow disabling
* translation
*
* @param OntoWiki_Message $message The message to be added.
*
* @return OntoWiki
*/
public function appendMessage(OntoWiki_Message $message)
{
$session = $this->getBootstrap()->getResource('Session');
$messageStack = (array)$session->messageStack;
array_push($messageStack, $message);
$session->messageStack = $messageStack;
return $this;
}
/**
* Appends an info message to the message stack, a convenient shortcut to
* appendMessage with included translate
*
* @param string $message The message to be added.
* @since 0.9.9
* @return OntoWiki
*/
public function appendInfoMessage($message)
{
$this->appendMessage(
new OntoWiki_Message((string)$message, OntoWiki_Message::INFO)
);
return $this;
}
/**
* Appends a success message to the message stack, a convenient shortcut to
* appendMessage with included translate
*
* @param string $message The message to be added.
* @since 0.9.9
* @return OntoWiki
*/
public function appendSuccessMessage($message)
{
$this->appendMessage(
new OntoWiki_Message((string)$message, OntoWiki_Message::SUCCESS)
);
return $this;
}
/**
* Appends a warning message to the message stack, a convenient shortcut to
* appendMessage with included translate
*
* @param string $message The message to be added.
* @since 0.9.9
* @return OntoWiki
*/
public function appendWarningMessage($message)
{
$this->appendMessage(
new OntoWiki_Message((string)$message, OntoWiki_Message::WARNING)
);
return $this;
}
/**
* Appends an error message to the message stack, a convenient shortcut to
* appendMessage with included translate
*
* @param string $message The message to be added.
* @since 0.9.9
* @return OntoWiki
*/
public function appendErrorMessage($message)
{
$this->appendMessage(
new OntoWiki_Message((string)$message, OntoWiki_Message::ERROR)
);
return $this;
}
/**
* Returns the current message stack and empties it.
*
* @since 0.9.5
* @return array
*/
public function drawMessages()
{
return $this->getMessages(true);
}
/**
* Returns the application bootstrap object
*
* @since 0.9.5
*/
public function getBootstrap()
{
if (null === $this->_bootstrap) {
$frontController = Zend_Controller_Front::getInstance();
$this->_bootstrap = $frontController->getParam('bootstrap');
}
return $this->_bootstrap;
}
/**
*
*/
public function setBootstrap($bootstrap)
{
$this->_bootstrap = $bootstrap;
}
/**
* Returns the system config object
*
* @since 0.9.5
* @return Zend_Config
*/
public function getConfig()
{
$bootstrap = $this->getBootstrap();
if ($bootstrap && $bootstrap->hasResource('Config')) {
return $this->getBootstrap()->getResource('Config');
}
}
/**
* Returns the system cache object
*
* @since 0.9.9
* @return Zend_Cache_Core
*/
public function getCache()
{
$bootstrap = $this->getBootstrap();
if ($bootstrap && $bootstrap->hasResource('Erfurt')) {
return $this->getBootstrap()->getResource('Erfurt')->getCache();
}
}
/**
* Returns the system worker frontend object
*
* todo: indicate a missing backend somehow
* todo: be robust against missing pecl stuff
*
* @since 0.9.11
* @return Erfurt_Worker_Frontend
*/
public function getWorkerFrontend()
{
if (null === $this->_workerFrontend) {
$bootstrap = $this->getBootstrap();
$workerFrontend = Erfurt_Worker_Frontend::getInstance();
$workerFrontend->setBackend('gearman');
$workerFrontend->setServers($bootstrap->config->worker->servers);
$this->_workerFrontend = $workerFrontend;
}
return $this->_workerFrontend;
}
/**
* uses the system worker backend to call an async job
*
* todo: log a warning message if worker backend is not available
*
* @param string $jobId The jobs identifier string
* @param mixed $workload The jobs workload (array, object)
*
* @since 0.9.11
* @return null
*/
public function callJob($jobId, $workload = array())
{
$client = $this->getWorkerFrontend();
$client->call($jobId, $workload);
}
/**
* Singleton instance
*
* @return OntoWiki
*/
public static function getInstance()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
return self::$_instance;
}
/**
* Returns a custom logger object.
* If the $identifier parameter is missing or is equal to the default log
* identifier, the default logger object is returned.
*
* @param string $identifier (optional)
*
* @return Zend_Log
*/
public function getCustomLogger($identifier = self::DEFAULT_LOG_IDENTIFIER)
{
if ($identifier === self::DEFAULT_LOG_IDENTIFIER) {
return $this->logger;
}
if (isset($this->_customLogs[$identifier])) {
return $this->_customLogs[$identifier];
}
$config = $this->getConfig();
// support absolute path
if (!(preg_match('/^(\w:[\/|\\\\]|\/)/', $config->log->path) === 1)) {
// prepend OntoWiki root for relative paths
$config->log->path = ONTOWIKI_ROOT . $config->log->path;
}
// initialize logger
if (is_writable($config->log->path) && ((boolean)$config->log->enabled == true)) {
$levelFilter = new Zend_Log_Filter_Priority((int)$config->log->level, '<=');
$writer = new Zend_Log_Writer_Stream($config->log->path . $identifier . '.log');
$logger = new Zend_Log($writer);
$logger->addFilter($levelFilter);
$this->_customLogs[$identifier] = $logger;
return $logger;
}
// fallback to NULL logger
$writer = new Zend_Log_Writer_Null();
$logger = new Zend_Log($writer);
return $logger;
}
/**
* Returns the current message stack and empties it.
*
* @param boolean $clearMessages Clears the message stack after retrieval
*
* @return array
*/
public function getMessages($clearMessages = false)
{
$session = $this->getBootstrap()->getResource('Session');
// store temporarily
$messageStack = (array)$this->session->messageStack;
if ($clearMessages) {
// empty message stack
unset($session->messageStack);
}
// return temp
return $messageStack;
}
/**
* Returns the base URL for static files.
* In case mod_rewrite is enabled, getUrlBase and getStaticUrlBase
* return identical results.
*
* @since 0.9.5
* @return string
*/
public function getStaticUrlBase()
{
if ($config = $this->getConfig()) {
return $config->staticUrlBase;
}
}
/**
* Returns the base URL for dynamic requests.
* In case mod_rewrite is enabled, getUrlBase and getStaticUrlBase
* return identical results.
*
* @since 0.9.5
* @return string
*/
public function getUrlBase()
{
if ($config = $this->getConfig()) {
return $config->urlBase;
}
}
/**
* Returns the currently logged-in user.
*
* @return Erfurt_Auth_Identity
*/
public function getUser()
{
return $this->user;
}
/**
* Returns whether OntoWiki currently has messages for the user.
*
* @return boolean
*/
public function hasMessages()
{
$messages = $this->getMessages();
return (!empty($messages));
}
/**
* Sets an array of variables that are to be synchronized
* with the session.
*
* @since 0.9.5
*
* @param array $sessionVars
*/
public function setSessionVars(array $sessionVars)
{
// add to session vars
$this->_sessionVars = $sessionVars;
}
/**
* Prepends a message to the message stack
*
* @param OntoWiki_Message $message The message to be added.
*
* @return OntoWiki
*/
public function prependMessage(OntoWiki_Message $message)
{
$session = $this->getBootstrap()->getResource('Session');
$messageStack = (array)$session->messageStack;
array_unshift($messageStack, $message);
$session->messageStack = $messageStack;
return $this;
}
/**
*
*/
public static function reset()
{
self::$_instance = null;
}
/**
*
*/
public function getNavigation()
{
if (null == $this->_navigation) {
$this->_navigation = new OntoWiki_Navigation();
}
return $this->_navigation;
}
}
================================================
FILE: application/config/SysBase/dc
================================================
]>
DCMI Namespace for the Dublin Core Metadata Element Set, Version 1.1To comment on this schema, please contact dcmifb@dublincore.org.The Dublin Core Metadata Initiative2008-01-14TitleA name given to the resource.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.CreatorAn entity primarily responsible for making the resource.Examples of a Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.SubjectThe topic of the resource.Typically, the subject will be represented using keywords, key phrases, or classification codes. Recommended best practice is to use a controlled vocabulary. To describe the spatial or temporal topic of the resource, use the Coverage element.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.DescriptionAn account of the resource.Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.PublisherAn entity responsible for making the resource available.Examples of a Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.ContributorAn entity responsible for making contributions to the resource.Examples of a Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.DateA point or period of time associated with an event in the lifecycle of the resource.Date may be used to express temporal information at any level of granularity. Recommended best practice is to use an encoding scheme, such as the W3CDTF profile of ISO 8601 [W3CDTF].1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.TypeThe nature or genre of the resource.Recommended best practice is to use a controlled vocabulary such as the DCMI Type Vocabulary [DCMITYPE]. To describe the file format, physical medium, or dimensions of the resource, use the Format element.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.FormatThe file format, physical medium, or dimensions of the resource.Examples of dimensions include size and duration. Recommended best practice is to use a controlled vocabulary such as the list of Internet Media Types [MIME].1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.IdentifierAn unambiguous reference to the resource within a given context.Recommended best practice is to identify the resource by means of a string conforming to a formal identification system. 1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.SourceA related resource from which the described resource is derived.The described resource may be derived from the related resource in whole or in part. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.LanguageA language of the resource.Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646].1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.RelationA related resource.Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. 1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.CoverageThe spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant.Spatial topic and spatial applicability may be a named place or a location specified by its geographic coordinates. Temporal topic may be a named period, date, or date range. A jurisdiction may be a named administrative entity or a geographic place to which the resource applies. Recommended best practice is to use a controlled vocabulary such as the Thesaurus of Geographic Names [TGN]. Where appropriate, named places or time periods can be used in preference to numeric identifiers such as sets of coordinates or date ranges.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.RightsInformation about rights held in and over the resource.Typically, rights information includes a statement about various property rights associated with the resource, including intellectual property rights.1999-07-022008-01-14A second property with the same name as this property has been declared in the dcterms: namespace (http://purl.org/dc/terms/). See the Introduction to the document "DCMI Metadata Terms" (http://dublincore.org/documents/dcmi-terms/) for an explanation.
================================================
FILE: application/config/SysBase/dcterms
================================================
]>
DCMI Namespace for metadata terms in the http://purl.org/dc/terms/ namespaceTo comment on this schema, please contact dcmifb@dublincore.org.The Dublin Core Metadata Initiative2008-01-14TitleA name given to the resource.2008-01-142008-01-14In current practice, this term is used primarily with literal values; however, there are important uses with non-literal values as well. As of December 2007, the DCMI Usage Board is leaving this range unspecified pending an investigation of options.CreatorAn entity primarily responsible for making the resource.Examples of a Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity.2008-01-142008-01-14SubjectThe topic of the resource.Typically, the subject will be represented using keywords, key phrases, or classification codes. Recommended best practice is to use a controlled vocabulary. To describe the spatial or temporal topic of the resource, use the Coverage element.2008-01-142008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.DescriptionAn account of the resource.Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource.2008-01-142008-01-14PublisherAn entity responsible for making the resource available.Examples of a Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity.2008-01-142008-01-14ContributorAn entity responsible for making contributions to the resource.Examples of a Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity.2008-01-142008-01-14DateA point or period of time associated with an event in the lifecycle of the resource.Date may be used to express temporal information at any level of granularity. Recommended best practice is to use an encoding scheme, such as the W3CDTF profile of ISO 8601 [W3CDTF].2008-01-142008-01-14TypeThe nature or genre of the resource.Recommended best practice is to use a controlled vocabulary such as the DCMI Type Vocabulary [DCMITYPE]. To describe the file format, physical medium, or dimensions of the resource, use the Format element.2008-01-142008-01-14FormatThe file format, physical medium, or dimensions of the resource.Examples of dimensions include size and duration. Recommended best practice is to use a controlled vocabulary such as the list of Internet Media Types [MIME].2008-01-142008-01-14IdentifierAn unambiguous reference to the resource within a given context.Recommended best practice is to identify the resource by means of a string conforming to a formal identification system. 2008-01-142008-01-14SourceA related resource from which the described resource is derived.The described resource may be derived from the related resource in whole or in part. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system.2008-01-142008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.LanguageA language of the resource.Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646].2008-01-142008-01-14RelationA related resource.Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. 2008-01-142008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.CoverageThe spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant.Spatial topic and spatial applicability may be a named place or a location specified by its geographic coordinates. Temporal topic may be a named period, date, or date range. A jurisdiction may be a named administrative entity or a geographic place to which the resource applies. Recommended best practice is to use a controlled vocabulary such as the Thesaurus of Geographic Names [TGN]. Where appropriate, named places or time periods can be used in preference to numeric identifiers such as sets of coordinates or date ranges.2008-01-142008-01-14RightsInformation about rights held in and over the resource.Typically, rights information includes a statement about various property rights associated with the resource, including intellectual property rights.2008-01-142008-01-14AudienceA class of entity for whom the resource is intended or useful.2001-05-212008-01-14Alternative TitleAn alternative name for the resource.The distinction between titles and alternative titles is application-specific.2000-07-112008-01-14In current practice, this term is used primarily with literal values; however, there are important uses with non-literal values as well. As of December 2007, the DCMI Usage Board is leaving this range unspecified pending an investigation of options.Table Of ContentsA list of subunits of the resource.2000-07-112008-01-14AbstractA summary of the resource.2000-07-112008-01-14Date CreatedDate of creation of the resource.2000-07-112008-01-14Date ValidDate (often a range) of validity of a resource.2000-07-112008-01-14Date AvailableDate (often a range) that the resource became or will become available.2000-07-112008-01-14Date IssuedDate of formal issuance (e.g., publication) of the resource.2000-07-112008-01-14Date ModifiedDate on which the resource was changed.2000-07-112008-01-14ExtentThe size or duration of the resource.2000-07-112008-01-14MediumThe material or physical carrier of the resource.2000-07-112008-01-14Is Version OfA related resource of which the described resource is a version, edition, or adaptation.Changes in version imply substantive changes in content rather than differences in format.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Has VersionA related resource that is a version, edition, or adaptation of the described resource.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Replaced ByA related resource that supplants, displaces, or supersedes the described resource.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.ReplacesA related resource that is supplanted, displaced, or superseded by the described resource.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Required ByA related resource that requires the described resource to support its function, delivery, or coherence.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.RequiresA related resource that is required by the described resource to support its function, delivery, or coherence.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Part OfA related resource in which the described resource is physically or logically included.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Has PartA related resource that is included either physically or logically in the described resource.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Referenced ByA related resource that references, cites, or otherwise points to the described resource.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.ReferencesA related resource that is referenced, cited, or otherwise pointed to by the described resource.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Format OfA related resource that is substantially the same as the described resource, but in another format.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Has FormatA related resource that is substantially the same as the pre-existing described resource, but in another format.2000-07-112008-01-14This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Conforms ToAn established standard to which the described resource conforms.2001-05-212008-01-14Spatial CoverageSpatial characteristics of the resource.2000-07-112008-01-14Temporal CoverageTemporal characteristics of the resource.2000-07-112008-01-14MediatorAn entity that mediates access to the resource and for whom the resource is intended or useful.In an educational context, a mediator might be a parent, teacher, teaching assistant, or care-giver.2001-05-212008-01-14Date AcceptedDate of acceptance of the resource.Examples of resources to which a Date Accepted may be relevant are a thesis (accepted by a university department) or an article (accepted by a journal).2002-07-132008-01-14Date CopyrightedDate of copyright.2002-07-132008-01-14Date SubmittedDate of submission of the resource.Examples of resources to which a Date Submitted may be relevant are a thesis (submitted to a university department) or an article (submitted to a journal).2002-07-132008-01-14Audience Education LevelA class of entity, defined in terms of progression through an educational or training context, for which the described resource is intended.2002-07-132008-01-14Access RightsInformation about who can access the resource or an indication of its security status.Access Rights may include information regarding access or restrictions based on privacy, security, or other policies.2003-02-152008-01-14Bibliographic CitationA bibliographic reference for the resource.Recommended practice is to include sufficient bibliographic detail to identify the resource as unambiguously as possible.2003-02-152008-01-14LicenseA legal document giving official permission to do something with the resource.2004-06-142008-01-14Rights HolderA person or organization owning or managing rights over the resource.2004-06-142008-01-14ProvenanceA statement of any changes in ownership and custody of the resource since its creation that are significant for its authenticity, integrity, and interpretation.The statement may include a description of any changes successive custodians made to the resource.2004-09-202008-01-14Instructional MethodA process, used to engender knowledge, attitudes and skills, that the described resource is designed to support.Instructional Method will typically include ways of presenting instructional materials or conducting instructional activities, patterns of learner-to-learner and learner-to-instructor interactions, and mechanisms by which group and individual levels of learning are measured. Instructional methods include all aspects of the instruction and learning processes from planning and implementation through evaluation and feedback.2005-06-132008-01-14Accrual MethodThe method by which items are added to a collection.2005-06-132008-01-14Accrual PeriodicityThe frequency with which items are added to a collection.2005-06-132008-01-14Accrual PolicyThe policy governing the addition of items to a collection.2005-06-132008-01-14AgentA resource that acts or has the power to act.Examples of Agent include person, organization, and software agent.2008-01-14Agent ClassA group of agents.Examples of Agent Class include groups seen as classes, such as students, women, charities, lecturers.2008-01-14Bibliographic ResourceA book, article, or other documentary resource.2008-01-14File FormatA digital resource format.Examples include the formats defined by the list of Internet Media Types.2008-01-14FrequencyA rate at which something recurs.2008-01-14JurisdictionThe extent or range of judicial, law enforcement, or other authority.2008-01-14License DocumentA legal document giving official permission to do something with a Resource.2008-01-14Linguistic SystemA system of signs, symbols, sounds, gestures, or rules used in communication.Examples include written, spoken, sign, and computer languages.2008-01-14LocationA spatial region or named place.2008-01-14Location, Period, or JurisdictionA location, period of time, or jurisdiction.2008-01-14Media TypeA file format or physical medium.2008-01-14Media Type or ExtentA media type or extent.2008-01-14Method of InstructionA process that is used to engender knowledge, attitudes, and skills.2008-01-14Method of AccrualA method by which resources are added to a collection.2008-01-14Period of TimeAn interval of time that is named or defined by its start and end dates.2008-01-14Physical MediumA physical material or carrier.Examples include paper, canvas, or DVD.2008-01-14Physical ResourceA material thing.2008-01-14PolicyA plan or course of action by an authority, intended to influence and determine decisions, actions, and other matters.2008-01-14Provenance StatementA statement of any changes in ownership and custody of a resource since its creation that are significant for its authenticity, integrity, and interpretation.2008-01-14Rights StatementA statement about the intellectual property rights (IPR) held in or over a Resource, a legal document giving official permission to do something with a resource, or a statement about access rights.2008-01-14Size or DurationA dimension or extent, or a time taken to play or execute.Examples include a number of pages, a specification of length, width, and breadth, or a period in hours, minutes, and seconds.2008-01-14StandardA basis for comparison; a reference point against which other things can be evaluated.2008-01-14ISO 639-2The three-letter alphabetic codes listed in ISO639-2 for the representation of names of languages.2000-07-112008-01-14RFC 1766The set of tags, constructed according to RFC 1766, for the identification of languages.2000-07-112008-01-14URIThe set of identifiers constructed according to the generic syntax for Uniform Resource Identifiers as specified by the Internet Engineering Task Force.2000-07-112008-01-14DCMI PointThe set of points in space defined by their geographic coordinates according to the DCMI Point Encoding Scheme.2000-07-112008-01-14ISO 3166The set of codes listed in ISO 3166-1 for the representation of names of countries.2000-07-112008-01-14DCMI BoxThe set of regions in space defined by their geographic coordinates according to the DCMI Box Encoding Scheme.2000-07-112008-01-14DCMI PeriodThe set of time intervals defined by their limits according to the DCMI Period Encoding Scheme.2000-07-112008-01-14W3C-DTFThe set of dates and times constructed according to the W3C Date and Time Formats Specification.2000-07-112008-01-14RFC 3066The set of tags constructed according to RFC 3066 for the identification of languages.RFC 3066 has been obsoleted by RFC 4646.2002-07-132008-01-14RFC 4646The set of tags constructed according to RFC 4646 for the identification of languages.RFC 4646 obsoletes RFC 3066.2008-01-14ISO 639-3The set of three-letter codes listed in ISO 639-3 for the representation of names of languages.2008-01-14LCSHThe set of labeled concepts specified by the Library of Congress Subject Headings.2000-07-112008-01-14MeSHThe set of labeled concepts specified by the Medical Subject Headings.2000-07-112008-01-14DDCThe set of conceptual resources specified by the Dewey Decimal Classification.2000-07-112008-01-14LCCThe set of conceptual resources specified by the Library of Congress Classification.2000-07-112008-01-14UDCThe set of conceptual resources specified by the Universal Decimal Classification.2000-07-112008-01-14DCMI Type VocabularyThe set of classes specified by the DCMI Type Vocabulary, used to categorize the nature or genre of the resource.2000-07-112008-01-14IMTThe set of media types specified by the Internet Assigned Numbers Authority.2000-07-112008-01-14TGNThe set of places specified by the Getty Thesaurus of Geographic Names.2000-07-112008-01-14NLMThe set of conceptual resources specified by the National Library of Medicine Classification.2005-06-132008-01-14
================================================
FILE: application/config/SysBase/foaf
================================================
================================================
FILE: application/config/SysBase/geo
================================================
WGS84 Geo Positioning: an RDF vocabularyA vocabulary for representing latitude, longitude and altitude information in the WGS84 geodetic reference datum. Version $Id: wgs84_pos.rdf,v 1.18 2006/02/01 22:01:04 danbri Exp $. See http://www.w3.org/2003/01/geo/ for more details.$Date: 2006/02/01 22:01:04 $geo
Recent changes to this namespace:
$Log: wgs84_pos.rdf,v $
Revision 1.18 2006/02/01 22:01:04 danbri
Clarified that lat and long are decimal degrees, and that alt is decimal metres about local reference ellipsoid
Revision 1.17 2004/02/06 17:38:12 danbri
Fixed a bad commit screwup
Revision 1.15 2003/04/19 11:24:08 danbri
Fixed the typo even more.
Revision 1.14 2003/04/19 11:16:56 danbri
fixed a typo
Revision 1.13 2003/02/19 22:27:27 connolly
relaxed domain constraints on lat/long/alt from Point to SpatialThing
Revision 1.12 2003/01/12 01:41:41 danbri
Trying local copy of XSLT doc.
Revision 1.11 2003/01/12 01:20:18 danbri
added a link to morten's xslt rdfs viewer.
Revision 1.10 2003/01/11 18:56:49 danbri
Removed datatype range from lat and long properties, since they would
have required each occurance of the property to mention the datatype.
Revision 1.9 2003/01/11 11:41:31 danbri
Another typo; repaired rdfs:Property to rdf:Property x4
Revision 1.8 2003/01/11 11:05:02 danbri
Added an rdfs:range for each lat/long/alt property,
http://www.w3.org/2001/XMLSchema#float
Revision 1.7 2003/01/10 20:25:16 danbri
Longer rdfs:comment for Point, trying to be Earth-centric and neutral about
coordinate system(s) at the same time. Feedback welcomed.
Revision 1.6 2003/01/10 20:18:30 danbri
Added CVS log comments into the RDF/XML as an rdfs:comment property of the
vocabulary. Note that this is not common practice (but seems both harmless
and potentially useful).
revision 1.5
date: 2003/01/10 20:14:31; author: danbri; state: Exp; lines: +16 -5
Updated schema:
Added a dc:date, added url for more info. Changed the rdfs:label of the
namespace from gp to geo. Added a class Point, set as the rdfs:domain of
each property. Added XML comment on the lat_long property suggesting that
we might not need it (based on #rdfig commentary from implementors).
revision 1.4
date: 2003/01/10 20:01:07; author: danbri; state: Exp; lines: +6 -5
Fixed typo; several rdfs:about attributes are now rdf:about. Thanks to MortenF in
#rdfig for catching this error.
revision 1.3
date: 2003/01/10 11:59:03; author: danbri; state: Exp; lines: +4 -3
fixed buglet in vocab, added more wgs links
revision 1.2
date: 2003/01/10 11:01:11; author: danbri; state: Exp; lines: +4 -4
Removed alt from the as-a-flat-string property, and switched from
space separated to comma separated.
revision 1.1
date: 2003/01/10 10:53:23; author: danbri; state: Exp;
basic geo vocab
SpatialThingAnything with spatial extent, i.e. size, shape, or position. e.g. people, places, bowling balls, as well as abstract areas like cubes.
PointA point, typically described using a coordinate system relative to Earth, such as WGS84.
Uniquely identified by lat/long/alt. i.e.
spaciallyIntersects(P1, P2) :- lat(P1, LAT), long(P1, LONG), alt(P1, ALT),
lat(P2, LAT), long(P2, LONG), alt(P2, ALT).
sameThing(P1, P2) :- type(P1, Point), type(P2, Point), spaciallyIntersects(P1, P2).
latitudeThe WGS84 latitude of a SpatialThing (decimal degrees).longitudeThe WGS84 longitude of a SpatialThing (decimal degrees).altitudeThe WGS84 altitude of a SpatialThing (decimal meters
above the local reference ellipsoid).lat/longA comma-separated representation of a latitude, longitude coordinate.
================================================
FILE: application/config/SysBase/owl
================================================
]>
This file specifies in RDF Schema format the
built-in classes and properties that together form the basis of
the RDF/XML syntax of OWL Full, OWL DL and OWL Lite.
We do not expect people to import this file
explicitly into their ontology. People that do import this file
should expect their ontology to be an OWL Full ontology.
10 February 2004, revised $Date: 2004/09/24 18:12:02 $ClassThingNothingequivalentClassdisjointWithequivalentPropertysameAsdifferentFromAllDifferentdistinctMembersunionOfintersectionOfcomplementOfoneOfRestrictiononPropertyallValuesFromhasValuesomeValuesFromminCardinalitymaxCardinalitycardinalityObjectPropertyDatatypePropertyinverseOfTransitivePropertySymmetricPropertyFunctionalPropertyInverseFunctionalPropertyAnnotationPropertyOntologyOntologyPropertyimportsversionInfopriorVersionbackwardCompatibleWithincompatibleWithDeprecatedClassDeprecatedPropertyDataRange
================================================
FILE: application/config/SysBase/rdf
================================================
The RDF Vocabulary (RDF)This is the RDF Schema for the RDF vocabulary defined in the RDF namespace.typeThe subject is an instance of a class.PropertyThe class of RDF properties.StatementThe class of RDF statements.subjectThe subject of the subject RDF statement.predicateThe predicate of the subject RDF statement.objectThe object of the subject RDF statement.BagThe class of unordered containers.SeqThe class of ordered containers.AltThe class of containers of alternatives.valueIdiomatic property used for structured values.ListThe class of RDF Lists.nilThe empty list, with no items in it. If the rest of a list is nil then the list has no more items in it.firstThe first item in the subject RDF list.restThe rest of the subject RDF list after the first item.XMLLiteralThe class of XML literal values.
================================================
FILE: application/config/SysBase/rdfs
================================================
ResourceThe class resource, everything.ClassThe class of classes.subClassOfThe subject is a subclass of a class.subPropertyOfThe subject is a subproperty of a property.commentA description of the subject resource.labelA human-readable name for the subject.domainA domain of the subject property.rangeA range of the subject property.seeAlsoFurther information about the subject resource.isDefinedByThe defininition of the subject resource.LiteralThe class of literal values, eg. textual strings and integers.ContainerThe class of RDF containers.ContainerMembershipPropertyThe class of container membership properties, rdf:_1, rdf:_2, ...,
all of which are sub-properties of 'member'.memberA member of the subject resource.DatatypeThe class of RDF datatypes.
================================================
FILE: application/config/SysBase/rel
================================================
text/htmlHTMLapplication/jsonJSONtext/plainTurtleRELATIONSHIP: A vocabulary for describing relationships between peopleA vocabulary for describing relationships between peoplehttp://purl.org/vocab/relationship/rel-vocab-20050810http://purl.org/vocab/relationshiprel2004-02-11Ian DavisEric Vitiello JrUsing With FOAFUsing With HTML and XHTMLAdded isDefinedBy properties and updated documentation2005-08-10Ian DavisTyped vocabulary as owl:Ontology2009-05-15Ian Davisfriend ofA person who shares mutual friendship with this person.acquaintance ofA person having more than slight or superficial knowledge of this person but short of friendship.parent ofA person who has given birth to or nurtured and raised this person.sibling ofA person having one or both parents in common with this person.child ofA person who was given birth to or nurtured and raised by this person.grandchild ofGrandchild OfA person who is a child of any of this person's children.spouse ofA person who is married to this personenemy ofA person towards whom this person feels hatred, intends injury to, or opposes the interests of.antagonist ofA person who opposes and contends against this person.ambivalent ofA person towards whom this person has mixed feelings or emotions.lost contact withA person who was once known by this person but has subsequently become uncontactable.knows ofA person who has come to be known to this person through their actions or position.would like to nowA person whom this person would desire to know more closely.knows in passingA person whom this person has slight or superficial knowledge of.knows by reputationA person known by this person primarily for a particular action, position or field of endeavour.close friend ofA person who shares a close mutual friendship with this person.has metA person who has met this person whether in passing or longer.works withA person who works for the same employer as this person.colleague ofA person who is a member of the same profession as this person.collaborates withA person who works towards a common goal with this person.employer ofA person who engages the services of this person.employed byA person for whom this person's services have been engaged.mentor ofA person who serves as a trusted counselor or teacher to this person.apprentice toA person to whom this person serves as a trusted counselor or teacher.lives withA person who shares a residence with this person.neighbor ofA person who lives in the same locality as this person.grandparent ofA person who is the parent of any of this person's parents.life partner ofA person who has made a long-term commitment to this person's.engaged toA person to whom this person is betrothed.ancestor ofA person who is a descendant of this person.Descendant Ofdescendant ofA person from whom this person is descended.relationshipA particular type of connection existing between people related to or having dealings with each other.participant inparticipantinfluenced bya person who has influenced this person.
================================================
FILE: application/config/SysBase/sioc
================================================
SIOC Core Ontology NamespaceRevision: 1.31SIOC (Semantically-Interlinked Online Communities) is an ontology for describing the information in online communities.
This information can be used to export information from online communities and to link them together. The scope of the application areas that SIOC can be used for includes (and is not limited to) weblogs, message boards, mailing lists and chat channels.CommunityCommunity is a high-level concept that defines an online community and what it consists of.ContainerAn area in which content Items are contained.ForumA discussion area on which Posts or entries are made.ItemAn Item is something which can be in a Container.PostAn article or message that can be posted to a Forum.RoleA Role is a function of a User within a scope of a particular Forum, Site, etc.SpaceA Space is a place where data resides, e.g. on a website, desktop, fileshare, etc.SiteA Site can be the location of an online community or set of communities, with Users and Usergroups creating Items in a set of Containers. It can be thought of as a web-accessible data Space.ThreadA container for a series of threaded discussion Posts or Items.UserA User account in an online community site.UsergroupA set of User accounts whose owners have a common purpose or interest. Can be used for access control purposes.aboutSpecifies that this Item is about a particular resource, e.g. a Post describing a book, hotel, etc.account_ofRefers to the foaf:Agent or foaf:Person who owns this sioc:User online account.administrator_ofA Site that the User is an administrator of.attachmentThe URI of a file attached to an Item.avatarAn image or depiction used to represent this User.container_ofAn Item that this Container contains.contentThe content of the Item in plain text format.creator_ofA resource that the User is a creator of.Links to a previous (older) revision of this Item or Post.earlier_versionemailAn electronic mail address of the User.email_sha1An electronic mail address of the User, encoded using SHA1.feedA feed (e.g. RSS, Atom, etc.) pertaining to this resource (e.g. for a Forum, Site, User, etc.).followsIndicates that one User follows another User (e.g. for microblog posts or other content item updates).function_ofA User who has this Role.has_administratorA User who is an administrator of this Site.has_containerThe Container to which this Item belongs.has_creatorThis is the User who made this resource.has_functionA Role that this User has.has_hostThe Site that hosts this Forum.has_memberA User who is a member of this Usergroup.has_moderatorA User who is a moderator of this Forum.has_modifierA User who modified this Item.has_ownerA User that this resource is owned by.has_parentA Container or Forum that this Container or Forum is a child of.has_replyPoints to an Item or Post that is a reply or response to this Item or Post.has_scopeA resource that this Role applies to.has_spaceA data Space which this resource is a part of.has_subscriberA User who is subscribed to this Container.has_usergroupPoints to a Usergroup that has certain access to this Space.host_ofA Forum that is hosted on this Site.idAn identifier of a SIOC concept instance. For example, a user ID. Must be unique for instances of each type of SIOC concept within the same site.ip_addressThe IP address used when creating this Item. This can be associated with a creator. Some wiki articles list the IP addresses for the creator or modifiers when the usernames are absent.Links to a later (newer) revision of this Item or Post.later_versionLinks to the latest revision of this Item or Post.latest_versionlinkA URI of a document which contains this SIOC object.links_toLinks extracted from hyperlinks within a SIOC concept, e.g. Post or Site.member_ofA Usergroup that this User is a member of.moderator_ofA Forum that User is a moderator of.modifier_ofAn Item that this User has modified.nameThe name of a SIOC instance, e.g. a username for a User, group name for a Usergroup, etc.next_by_dateNext Item or Post in a given Container sorted by date.next_versionLinks to the next revision of this Item or Post.noteA note associated with this resource, for example, if it has been edited by a User.num_repliesThe number of replies that this Item, Thread, Post, etc. has. Useful for when the reply structure is absent.num_viewsThe number of times this Item, Thread, User profile, etc. has been viewed.owner_ofA resource owned by a particular User, for example, a weblog or image gallery.parent_ofA child Container or Forum that this Container or Forum is a parent of.previous_by_datePrevious Item or Post in a given Container sorted by date.previous_versionLinks to the previous revision of this Item or Post.related_toRelated Posts for this Post, perhaps determined implicitly from topics or references.reply_ofLinks to an Item or Post which this Item or Post is a reply to.scope_ofA Role that has a scope of this resource.siblingAn Item may have a sibling or a twin that exists in a different Container, but the siblings may differ in some small way (for example, language, category, etc.). The sibling of this Item should be self-describing (that is, it should contain all available information).space_ofA resource which belongs to this data Space.subscriber_ofA Container that a User is subscribed to.topicA topic of interest, linking to the appropriate URI, e.g. in the Open Directory Project or of a SKOS category.usergroup_ofA Space that the Usergroup has access to.titleThis is the title (subject line) of the Post. Note that for a Post within a threaded discussion that has no parents, it would detail the topic thread.This property is deprecated. Use dcterms:title from the Dublin Core ontology instead.content_encodedThe encoded content of the Post, contained in CDATA areas.This property is deprecated. Use content:encoded from the RSS 1.0 content module instead.created_atWhen this was created, in ISO 8601 format.This property is deprecated. Use dcterms:created from the Dublin Core ontology instead.descriptionThe content of the Post.This property is deprecated. Use sioc:content or other methods (AtomOwl, content:encoded from RSS 1.0, etc.) instead.first_nameFirst (real) name of this User. Synonyms include given name or christian name.This property is deprecated. Use foaf:name or foaf:firstName from the FOAF vocabulary instead.group_ofThis property has been renamed. Use sioc:usergroup_of instead.The discussion that is related to this Item.has_discussionhas_groupThis property has been renamed. Use sioc:has_usergroup instead.has_partAn resource that is a part of this subject.This property is deprecated. Use dcterms:hasPart from the Dublin Core ontology instead.last_nameLast (real) name of this user. Synonyms include surname or family name.This property is deprecated. Use foaf:name or foaf:surname from the FOAF vocabulary instead.modified_atWhen this was modified, in ISO 8601 format.This property is deprecated. Use dcterms:modified from the Dublin Core ontology instead.part_ofA resource that the subject is a part of.This property is deprecated. Use dcterms:isPartOf from the Dublin Core ontology instead.referenceLinks either created explicitly or extracted implicitly on the HTML level from the Post.Renamed to sioc:links_to.subjectKeyword(s) describing subject of the Post.This property is deprecated. Use dcterms:subject from the Dublin Core ontology for text keywords and sioc:topic if the subject can be represented by a URI instead.
================================================
FILE: application/config/SysBase/sioct
================================================
SIOC Types Ontology Module NamespaceExtends the SIOC Core Ontology (Semantically-Interlinked Online Communities) by defining subclasses and subproperties of SIOC terms.Address BookDescribes a collection of personal or organisational addresses.Annotation SetDescribes a set of annotations, for example, those created by a particular user or related to a particular topic.Audio ChannelDescribes a channel for distributing audio or sound files, for example, a podcast.Bookmark FolderDescribes a shared collection of bookmarks.BriefcaseDescribes a briefcase or file service.Event CalendarDescribes a calendar of events.Image GalleryDescribes an image gallery, for example, a photo album.Project DirectoryDescribes a project directory.Resume BankDescribes a collection of resumes.Review AreaDescribes an area where reviews are posted.Subscription ListDescribes a shared set of feed subscriptions.Survey CollectionDescribes an area where survey data can be collected, e.g. from polls.Video ChannelDescribes a channel for distributing videos (moving image) files, for example, a video podcast.WikiDescribes a wiki space.Favourite ThingsDescribes a list or a collection of one's favourite things.Offer ListDescribes a list of the items someone has available to offer.PlaylistDescribes a list of media items that have been played or can be played.Reading ListDescribes a list of books or other materials that have been read or are suggested for reading.Wish ListDescribes a list of the items someone wishes to get.Argumentative DiscussionDescribes a discussion area where logical arguments can take place.Chat ChannelDescribes a channel for chat or instant messages, for example, via IRC or IM.Mailing ListDescribes an electronic mailing list.Message BoardDescribes a message board, also known as an online bulletin board or discussion forum.MicroblogDescribes a microblog, i.e. a blog consisting of short text messages.WeblogDescribes a weblog (blog), i.e. an online journal.PollDescribes a posted item that contains a poll or survey content.Blog PostDescribes a post that is specifically made on a weblog.Board PostDescribes a post that is specifically made on a message board.CommentComment is a subtype of sioc:Post and allows one to explicitly indicate that this SIOC post is a comment. Note that comments have a narrower scope than sioc:Post and may not apply to all types of community site.Instant MessageDescribes an instant message, e.g. sent via Jabber.Mail MessageDescribes an electronic mail message, e.g. a post sent to a mailing list.Microblog PostDescribes a post that is specifically made on a microblog.Wiki ArticleDescribes a wiki article.AnswerA Post that provides an answer in reply to a Question.Best AnswerA Post that is the best answer to a Question, as chosen by the User who asked the Question or as voted by a Community of Users.QuestionA Post that asks a Question.CategoryCategory is used on the object of sioc:topic to indicate that this resource is a category on a site.TagTag is used on the object of sioc:topic to indicate that this resource is a tag on a site.
================================================
FILE: application/config/SysBase/skos
================================================
SKOS VocabularyDave BeckettNikki RogersParticipants in W3C's Semantic Web Deployment Working Group.An RDF vocabulary for describing the basic structure and content of concept schemes such as thesauri, classification schemes, subject heading lists, taxonomies, 'folksonomies', other types of controlled vocabulary, and also concept schemes embedded in glossaries and terminologies.Alistair MilesSean BechhoferConceptAn idea or notion; a unit of thought.Concept SchemeA set of concepts, optionally including statements about semantic relationships between those concepts.A concept scheme may be defined to include concepts from different sources.Thesauri, classification schemes, subject heading lists, taxonomies, 'folksonomies', and other types of controlled vocabulary are all examples of concept schemes. Concept schemes are also embedded in glossaries and terminologies.CollectionA meaningful collection of concepts.Labelled collections can be used where you would like a set of concepts to be displayed under a 'node label' in the hierarchy.Ordered CollectionAn ordered collection of concepts, where both the grouping and the ordering are meaningful.Ordered collections can be used where you would like a set of concepts to be displayed in a specific order, and optionally under a 'node label'.is in schemeRelates a resource (for example a concept) to a concept scheme in which it is included.A concept may be a member of more than one concept scheme.has top conceptRelates, by convention, a concept scheme to a concept which is topmost in the broader/narrower concept hierarchies for that scheme, providing an entry point to these hierarchies.is top concept in schemeRelates a concept to the concept scheme that it is a top level concept of.preferred labelThe preferred lexical label for a resource, in a given language.A resource has no more than one value of skos:prefLabel per language tag.The range of skos:prefLabel is the class of RDF plain literals.skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise
disjoint properties.alternative labelAn alternative lexical label for a resource.Acronyms, abbreviations, spelling variants, and irregular plural/singular forms may be included among the alternative labels for a concept. Mis-spelled terms are normally included as hidden labels (see skos:hiddenLabel).The range of skos:altLabel is the class of RDF plain literals.skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise disjoint properties.hidden labelA lexical label for a resource that should be hidden when generating visual displays of the resource, but should still be accessible to free text search operations.The range of skos:hiddenLabel is the class of RDF plain literals.skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise disjoint properties.notationA notation, also known as classification code, is a string of characters such as "T58.5" or "303.4833" used to uniquely identify a concept within the scope of a given concept scheme.By convention, skos:notation is used with a typed literal in the object position of the triple.noteA general note, for any purpose.This property may be used directly, or as a super-property for more specific note types.change noteA note about a modification to a concept.definitionA statement or formal explanation of the meaning of a concept.editorial noteA note for an editor, translator or maintainer of the vocabulary.exampleAn example of the use of a concept.history noteA note about the past state/use/meaning of a concept.scope noteA note that helps to clarify the meaning and/or the use of a concept.is in semantic relation withLinks a concept to a concept related by meaning.This property should not be used directly, but as a super-property for all properties denoting a relationship of meaning between concepts.has broader conceptRelates a concept to a concept that is more general in meaning.Broader concepts are typically rendered as parents in a concept hierarchy (tree).By convention, skos:broader is only used to assert an immediate (i.e. direct) hierarchical link between two conceptual resources.has narrower conceptRelates a concept to a concept that is more specific in meaning.By convention, skos:broader is only used to assert an immediate (i.e. direct) hierarchical link between two conceptual resources.Narrower concepts are typically rendered as children in a concept hierarchy (tree).has related conceptRelates a concept to a concept with which there is an associative semantic relationship.skos:related is disjoint with skos:broaderTransitivehas broader transitiveskos:broaderTransitive is a transitive superproperty of skos:broader.By convention, skos:broaderTransitive is not used to make assertions. Rather, the properties can be used to draw inferences about the transitive closure of the hierarchical relation, which is useful e.g. when implementing a simple query expansion algorithm in a search application.has narrower transitiveskos:narrowerTransitive is a transitive superproperty of skos:narrower.By convention, skos:narrowerTransitive is not used to make assertions. Rather, the properties can be used to draw inferences about the transitive closure of the hierarchical relation, which is useful e.g. when implementing a simple query expansion algorithm in a search application.has memberRelates a collection to one of its members.has member listRelates an ordered collection to the RDF list containing its members.For any resource, every item in the list given as the value of the
skos:memberList property is also a value of the skos:member property.is in mapping relation withRelates two concepts coming, by convention, from different schemes, and that have comparable meaningsThese concept mapping relations mirror semantic relations, and the data model defined below is similar (with the exception of skos:exactMatch) to the data model defined for semantic relations. A distinct vocabulary is provided for concept mapping relations, to provide a convenient way to differentiate links within a concept scheme from links between concept schemes. However, this pattern of usage is not a formal requirement of the SKOS data model, and relies on informal definitions of best practice.has broader matchskos:broadMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes.has narrower matchskos:narrowMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes.has related matchskos:relatedMatch is used to state an associative mapping link between two conceptual resources in different concept schemes.has exact matchskos:exactMatch is used to link two concepts, indicating a high degree of confidence that the concepts can be used interchangeably across a wide range of information retrieval applications. skos:exactMatch is a transitive property, and is a sub-property of skos:closeMatch.skos:exactMatch is disjoint with each of the properties skos:broadMatch and skos:relatedMatch.has close matchskos:closeMatch is used to link two concepts that are sufficiently similar that they can be used interchangeably in some information retrieval applications. In order to avoid the possibility of "compound errors" when combining mappings across more than two concept schemes, skos:closeMatch is not declared to be a transitive property.
================================================
FILE: application/config/SysBase/tags
================================================
Danny AyersSeth RussellRichard NewmanAn ontology that describes tags, as used in the popular del.icio.us and Flickr systems, and allows for relationships between tags to be described.Tag ontology2005-03-232005-05-192005-11-272005-12-21A Tagging which has precisely one associated resource, and one associated tag.11A natural-language concept which is used to annotate another resource.A reified class which defines an instance of a tagging by an agent of a resource with one or more tags.testingThe object is a Tag which plays a role in the subject Tagging.testingThe two tags are asserted to be equivalent --- that is, that whenever one is associated with a resource, the other tag can be logically inferred to also be associated. Be very careful with this. I'm not sure if this should be a subproperty of owl:sameAs.testingIndicates that the subject tag applies to the object resource. This does not assert by who, when, or why the tagging occurred. For that information, use a reified Tagging resource.The name of a tag. Note that we can't relate this to skos:prefLabel because we cannot guarantee that tags have unique labels in a given conceptual scheme. Or can we?The two tags are asserted as being related. This might be symmetric, but it certainly isn't transitive.testingThe relationship between a resource and a Tagging. Note, of course, that this allows us to tag tags and taggings themselves...The name of a tag. Note that we can't relate this to skos:prefLabel because we cannot guarantee that tags have unique labels in a given conceptual scheme. Or can we? DEPRECATED 2005-05-19: redundant 'tag'.The object plays the role of the tagger in the subject Tagging.testingThe subject Tagging occurred at the subject time and date.testingThe object is a resource which plays a role in the subject Tagging.testingIndicates that the subject has been tagged with the object tag. This does not assert by who, when, or why the tagging occurred. For that information, use a reified Tagging resource.
================================================
FILE: application/config/SysBase.rdf
================================================
]>
OntoWiki System Base$Id: SysBase.rdf 4285 2009-10-12 13:15:09Z sebastian.dietzold $This is a collection of several property and class descriptions intended to be imported automatically.This model consists of all statements from the RDF, RDFS, OWL, DC, DCTERMS, SKOS, FOAF, SIOC and GEO namespaces to provide proper labels for standard properties and support better resource selection for standard object properties.Do NOT import this ontology directly! Instead, use the original resources you got from the seeAlso links.Inside OntoWiki, this model is used for the following tasks: (1) property selection in edit widgets (2) property labels in several tabs and modules.typeThe subject is an instance of a class.PropertyThe class of RDF properties.StatementThe class of RDF statements.subjectThe subject of the subject RDF statement.predicateThe predicate of the subject RDF statement.objectThe object of the subject RDF statement.BagThe class of unordered containers.SeqThe class of ordered containers.AltThe class of containers of alternatives.valueIdiomatic property used for structured values.ListThe class of RDF Lists.nilThe empty list, with no items in it. If the rest of a list is nil then the list has no more items in it.firstThe first item in the subject RDF list.restThe rest of the subject RDF list after the first item.XMLLiteralThe class of XML literal values.ResourceThe class resource, everything.ClassThe class of classes.subClassOfThe subject is a subclass of a class.subPropertyOfThe subject is a subproperty of a property.commentA description of the subject resource.labelA human-readable name for the subject.domainA domain of the subject property.rangeA range of the subject property.seeAlsoFurther information about the subject resource.isDefinedByThe defininition of the subject resource.LiteralThe class of literal values, eg. textual strings and integers.ContainerThe class of RDF containers.ContainerMembershipPropertyThe class of container membership properties, rdf:_1, rdf:_2, ...,
all of which are sub-properties of 'member'.memberA member of the subject resource.DatatypeThe class of RDF datatypes.ClassThingNothingequivalentClassdisjointWithequivalentPropertysameAsdifferentFromAllDifferentdistinctMembersunionOfintersectionOfcomplementOfoneOfRestrictiononPropertyallValuesFromhasValuesomeValuesFromminCardinalitymaxCardinalitycardinalityObjectPropertyDatatypePropertyinverseOfTransitivePropertySymmetricPropertyFunctionalPropertyInverseFunctionalPropertyAnnotationPropertyOntologyOntologyPropertyimportsversionInfopriorVersionbackwardCompatibleWithincompatibleWithDeprecatedClassDeprecatedPropertyDataRangeTitleA name given to the resource.CreatorAn entity primarily responsible for making the resource.Examples of a Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity.SubjectThe topic of the resource.Typically, the subject will be represented using keywords, key phrases, or classification codes. Recommended best practice is to use a controlled vocabulary. To describe the spatial or temporal topic of the resource, use the Coverage element.DescriptionAn account of the resource.Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource.PublisherAn entity responsible for making the resource available.Examples of a Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity.ContributorAn entity responsible for making contributions to the resource.Examples of a Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity.DateA point or period of time associated with an event in the lifecycle of the resource.Date may be used to express temporal information at any level of granularity. Recommended best practice is to use an encoding scheme, such as the W3CDTF profile of ISO 8601 [W3CDTF].TypeThe nature or genre of the resource.Recommended best practice is to use a controlled vocabulary such as the DCMI Type Vocabulary [DCMITYPE]. To describe the file format, physical medium, or dimensions of the resource, use the Format element.FormatThe file format, physical medium, or dimensions of the resource.Examples of dimensions include size and duration. Recommended best practice is to use a controlled vocabulary such as the list of Internet Media Types [MIME].IdentifierAn unambiguous reference to the resource within a given context.Recommended best practice is to identify the resource by means of a string conforming to a formal identification system. SourceA related resource from which the described resource is derived.The described resource may be derived from the related resource in whole or in part. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system.LanguageA language of the resource.Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646].RelationA related resource.Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. CoverageThe spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant.Spatial topic and spatial applicability may be a named place or a location specified by its geographic coordinates. Temporal topic may be a named period, date, or date range. A jurisdiction may be a named administrative entity or a geographic place to which the resource applies. Recommended best practice is to use a controlled vocabulary such as the Thesaurus of Geographic Names [TGN]. Where appropriate, named places or time periods can be used in preference to numeric identifiers such as sets of coordinates or date ranges.RightsInformation about rights held in and over the resource.Typically, rights information includes a statement about various property rights associated with the resource, including intellectual property rights.TitleA name given to the resource.In current practice, this term is used primarily with literal values; however, there are important uses with non-literal values as well. As of December 2007, the DCMI Usage Board is leaving this range unspecified pending an investigation of options.CreatorAn entity primarily responsible for making the resource.Examples of a Creator include a person, an organization, or a service. Typically, the name of a Creator should be used to indicate the entity.SubjectThe topic of the resource.Typically, the subject will be represented using keywords, key phrases, or classification codes. Recommended best practice is to use a controlled vocabulary. To describe the spatial or temporal topic of the resource, use the Coverage element.This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.DescriptionAn account of the resource.Description may include but is not limited to: an abstract, a table of contents, a graphical representation, or a free-text account of the resource.PublisherAn entity responsible for making the resource available.Examples of a Publisher include a person, an organization, or a service. Typically, the name of a Publisher should be used to indicate the entity.ContributorAn entity responsible for making contributions to the resource.Examples of a Contributor include a person, an organization, or a service. Typically, the name of a Contributor should be used to indicate the entity.DateA point or period of time associated with an event in the lifecycle of the resource.Date may be used to express temporal information at any level of granularity. Recommended best practice is to use an encoding scheme, such as the W3CDTF profile of ISO 8601 [W3CDTF].TypeThe nature or genre of the resource.Recommended best practice is to use a controlled vocabulary such as the DCMI Type Vocabulary [DCMITYPE]. To describe the file format, physical medium, or dimensions of the resource, use the Format element.FormatThe file format, physical medium, or dimensions of the resource.Examples of dimensions include size and duration. Recommended best practice is to use a controlled vocabulary such as the list of Internet Media Types [MIME].IdentifierAn unambiguous reference to the resource within a given context.Recommended best practice is to identify the resource by means of a string conforming to a formal identification system. SourceA related resource from which the described resource is derived.The described resource may be derived from the related resource in whole or in part. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system.This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.LanguageA language of the resource.Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646].RelationA related resource.Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.CoverageThe spatial or temporal topic of the resource, the spatial applicability of the resource, or the jurisdiction under which the resource is relevant.Spatial topic and spatial applicability may be a named place or a location specified by its geographic coordinates. Temporal topic may be a named period, date, or date range. A jurisdiction may be a named administrative entity or a geographic place to which the resource applies. Recommended best practice is to use a controlled vocabulary such as the Thesaurus of Geographic Names [TGN]. Where appropriate, named places or time periods can be used in preference to numeric identifiers such as sets of coordinates or date ranges.RightsInformation about rights held in and over the resource.Typically, rights information includes a statement about various property rights associated with the resource, including intellectual property rights.AudienceA class of entity for whom the resource is intended or useful.2001-05-21Alternative TitleAn alternative name for the resource.The distinction between titles and alternative titles is application-specific.2000-07-11In current practice, this term is used primarily with literal values; however, there are important uses with non-literal values as well. As of December 2007, the DCMI Usage Board is leaving this range unspecified pending an investigation of options.Table Of ContentsA list of subunits of the resource.2000-07-11AbstractA summary of the resource.2000-07-11Date CreatedDate of creation of the resource.2000-07-11Date ValidDate (often a range) of validity of a resource.2000-07-11Date AvailableDate (often a range) that the resource became or will become available.2000-07-11Date IssuedDate of formal issuance (e.g., publication) of the resource.2000-07-11Date ModifiedDate on which the resource was changed.2000-07-11ExtentThe size or duration of the resource.2000-07-11MediumThe material or physical carrier of the resource.2000-07-11Is Version OfA related resource of which the described resource is a version, edition, or adaptation.Changes in version imply substantive changes in content rather than differences in format.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Has VersionA related resource that is a version, edition, or adaptation of the described resource.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Replaced ByA related resource that supplants, displaces, or supersedes the described resource.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.ReplacesA related resource that is supplanted, displaced, or superseded by the described resource.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Required ByA related resource that requires the described resource to support its function, delivery, or coherence.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.RequiresA related resource that is required by the described resource to support its function, delivery, or coherence.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Part OfA related resource in which the described resource is physically or logically included.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Has PartA related resource that is included either physically or logically in the described resource.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Referenced ByA related resource that references, cites, or otherwise points to the described resource.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.ReferencesA related resource that is referenced, cited, or otherwise pointed to by the described resource.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Is Format OfA related resource that is substantially the same as the described resource, but in another format.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Has FormatA related resource that is substantially the same as the pre-existing described resource, but in another format.2000-07-11This term is intended to be used with non-literal values as defined in the DCMI Abstract Model (http://dublincore.org/documents/abstract-model/). As of December 2007, the DCMI Usage Board is seeking a way to express this intention with a formal range declaration.Conforms ToAn established standard to which the described resource conforms.2001-05-21Spatial CoverageSpatial characteristics of the resource.2000-07-11Temporal CoverageTemporal characteristics of the resource.2000-07-11MediatorAn entity that mediates access to the resource and for whom the resource is intended or useful.In an educational context, a mediator might be a parent, teacher, teaching assistant, or care-giver.2001-05-21Date AcceptedDate of acceptance of the resource.Examples of resources to which a Date Accepted may be relevant are a thesis (accepted by a university department) or an article (accepted by a journal).2002-07-13Date CopyrightedDate of copyright.2002-07-13Date SubmittedDate of submission of the resource.Examples of resources to which a Date Submitted may be relevant are a thesis (submitted to a university department) or an article (submitted to a journal).2002-07-13Audience Education LevelA class of entity, defined in terms of progression through an educational or training context, for which the described resource is intended.2002-07-13Access RightsInformation about who can access the resource or an indication of its security status.Access Rights may include information regarding access or restrictions based on privacy, security, or other policies.2003-02-15Bibliographic CitationA bibliographic reference for the resource.Recommended practice is to include sufficient bibliographic detail to identify the resource as unambiguously as possible.2003-02-15LicenseA legal document giving official permission to do something with the resource.2004-06-14Rights HolderA person or organization owning or managing rights over the resource.2004-06-14ProvenanceA statement of any changes in ownership and custody of the resource since its creation that are significant for its authenticity, integrity, and interpretation.The statement may include a description of any changes successive custodians made to the resource.2004-09-20Instructional MethodA process, used to engender knowledge, attitudes and skills, that the described resource is designed to support.Instructional Method will typically include ways of presenting instructional materials or conducting instructional activities, patterns of learner-to-learner and learner-to-instructor interactions, and mechanisms by which group and individual levels of learning are measured. Instructional methods include all aspects of the instruction and learning processes from planning and implementation through evaluation and feedback.2005-06-13Accrual MethodThe method by which items are added to a collection.2005-06-13Accrual PeriodicityThe frequency with which items are added to a collection.2005-06-13Accrual PolicyThe policy governing the addition of items to a collection.2005-06-13AgentA resource that acts or has the power to act.Examples of Agent include person, organization, and software agent.Agent ClassA group of agents.Examples of Agent Class include groups seen as classes, such as students, women, charities, lecturers.Bibliographic ResourceA book, article, or other documentary resource.File FormatA digital resource format.Examples include the formats defined by the list of Internet Media Types.FrequencyA rate at which something recurs.JurisdictionThe extent or range of judicial, law enforcement, or other authority.License DocumentA legal document giving official permission to do something with a Resource.Linguistic SystemA system of signs, symbols, sounds, gestures, or rules used in communication.Examples include written, spoken, sign, and computer languages.LocationA spatial region or named place.Location, Period, or JurisdictionA location, period of time, or jurisdiction.Media TypeA file format or physical medium.Media Type or ExtentA media type or extent.Method of InstructionA process that is used to engender knowledge, attitudes, and skills.Method of AccrualA method by which resources are added to a collection.Period of TimeAn interval of time that is named or defined by its start and end dates.Physical MediumA physical material or carrier.Examples include paper, canvas, or DVD.Physical ResourceA material thing.PolicyA plan or course of action by an authority, intended to influence and determine decisions, actions, and other matters.Provenance StatementA statement of any changes in ownership and custody of a resource since its creation that are significant for its authenticity, integrity, and interpretation.Rights StatementA statement about the intellectual property rights (IPR) held in or over a Resource, a legal document giving official permission to do something with a resource, or a statement about access rights.Size or DurationA dimension or extent, or a time taken to play or execute.Examples include a number of pages, a specification of length, width, and breadth, or a period in hours, minutes, and seconds.StandardA basis for comparison; a reference point against which other things can be evaluated.ISO 639-2The three-letter alphabetic codes listed in ISO639-2 for the representation of names of languages.2000-07-11RFC 1766The set of tags, constructed according to RFC 1766, for the identification of languages.2000-07-11URIThe set of identifiers constructed according to the generic syntax for Uniform Resource Identifiers as specified by the Internet Engineering Task Force.2000-07-11DCMI PointThe set of points in space defined by their geographic coordinates according to the DCMI Point Encoding Scheme.2000-07-11ISO 3166The set of codes listed in ISO 3166-1 for the representation of names of countries.2000-07-11DCMI BoxThe set of regions in space defined by their geographic coordinates according to the DCMI Box Encoding Scheme.2000-07-11DCMI PeriodThe set of time intervals defined by their limits according to the DCMI Period Encoding Scheme.2000-07-11W3C-DTFThe set of dates and times constructed according to the W3C Date and Time Formats Specification.2000-07-11RFC 3066The set of tags constructed according to RFC 3066 for the identification of languages.RFC 3066 has been obsoleted by RFC 4646.2002-07-13RFC 4646The set of tags constructed according to RFC 4646 for the identification of languages.RFC 4646 obsoletes RFC 3066.ISO 639-3The set of three-letter codes listed in ISO 639-3 for the representation of names of languages.ConceptAn idea or notion; a unit of thought.Concept SchemeA set of concepts, optionally including statements about semantic relationships between those concepts.A concept scheme may be defined to include concepts from different sources.Thesauri, classification schemes, subject heading lists, taxonomies, 'folksonomies', and other types of controlled vocabulary are all examples of concept schemes. Concept schemes are also embedded in glossaries and terminologies.CollectionA meaningful collection of concepts.Labelled collections can be used where you would like a set of concepts to be displayed under a 'node label' in the hierarchy.Ordered CollectionAn ordered collection of concepts, where both the grouping and the ordering are meaningful.Ordered collections can be used where you would like a set of concepts to be displayed in a specific order, and optionally under a 'node label'.is in schemeRelates a resource (for example a concept) to a concept scheme in which it is included.A concept may be a member of more than one concept scheme.has top conceptRelates, by convention, a concept scheme to a concept which is topmost in the broader/narrower concept hierarchies for that scheme, providing an entry point to these hierarchies.is top concept in schemeRelates a concept to the concept scheme that it is a top level concept of.preferred labelThe preferred lexical label for a resource, in a given language.A resource has no more than one value of skos:prefLabel per language tag.The range of skos:prefLabel is the class of RDF plain literals.skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise
disjoint properties.alternative labelAn alternative lexical label for a resource.Acronyms, abbreviations, spelling variants, and irregular plural/singular forms may be included among the alternative labels for a concept. Mis-spelled terms are normally included as hidden labels (see skos:hiddenLabel).The range of skos:altLabel is the class of RDF plain literals.skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise disjoint properties.hidden labelA lexical label for a resource that should be hidden when generating visual displays of the resource, but should still be accessible to free text search operations.The range of skos:hiddenLabel is the class of RDF plain literals.skos:prefLabel, skos:altLabel and skos:hiddenLabel are pairwise disjoint properties.notationA notation, also known as classification code, is a string of characters such as "T58.5" or "303.4833" used to uniquely identify a concept within the scope of a given concept scheme.By convention, skos:notation is used with a typed literal in the object position of the triple.noteA general note, for any purpose.This property may be used directly, or as a super-property for more specific note types.change noteA note about a modification to a concept.definitionA statement or formal explanation of the meaning of a concept.editorial noteA note for an editor, translator or maintainer of the vocabulary.exampleAn example of the use of a concept.history noteA note about the past state/use/meaning of a concept.scope noteA note that helps to clarify the meaning and/or the use of a concept.is in semantic relation withLinks a concept to a concept related by meaning.This property should not be used directly, but as a super-property for all properties denoting a relationship of meaning between concepts.has broader conceptRelates a concept to a concept that is more general in meaning.Broader concepts are typically rendered as parents in a concept hierarchy (tree).By convention, skos:broader is only used to assert an immediate (i.e. direct) hierarchical link between two conceptual resources.has narrower conceptRelates a concept to a concept that is more specific in meaning.By convention, skos:broader is only used to assert an immediate (i.e. direct) hierarchical link between two conceptual resources.Narrower concepts are typically rendered as children in a concept hierarchy (tree).has related conceptRelates a concept to a concept with which there is an associative semantic relationship.skos:related is disjoint with skos:broaderTransitivehas broader transitiveskos:broaderTransitive is a transitive superproperty of skos:broader.By convention, skos:broaderTransitive is not used to make assertions. Rather, the properties can be used to draw inferences about the transitive closure of the hierarchical relation, which is useful e.g. when implementing a simple query expansion algorithm in a search application.has narrower transitiveskos:narrowerTransitive is a transitive superproperty of skos:narrower.By convention, skos:narrowerTransitive is not used to make assertions. Rather, the properties can be used to draw inferences about the transitive closure of the hierarchical relation, which is useful e.g. when implementing a simple query expansion algorithm in a search application.has memberRelates a collection to one of its members.has member listRelates an ordered collection to the RDF list containing its members.For any resource, every item in the list given as the value of the
skos:memberList property is also a value of the skos:member property.is in mapping relation withRelates two concepts coming, by convention, from different schemes, and that have comparable meaningsThese concept mapping relations mirror semantic relations, and the data model defined below is similar (with the exception of skos:exactMatch) to the data model defined for semantic relations. A distinct vocabulary is provided for concept mapping relations, to provide a convenient way to differentiate links within a concept scheme from links between concept schemes. However, this pattern of usage is not a formal requirement of the SKOS data model, and relies on informal definitions of best practice.has broader matchskos:broadMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes.has narrower matchskos:narrowMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes.has related matchskos:relatedMatch is used to state an associative mapping link between two conceptual resources in different concept schemes.has exact matchskos:exactMatch is used to link two concepts, indicating a high degree of confidence that the concepts can be used interchangeably across a wide range of information retrieval applications. skos:exactMatch is a transitive property, and is a sub-property of skos:closeMatch.skos:exactMatch is disjoint with each of the properties skos:broadMatch and skos:relatedMatch.has close matchskos:closeMatch is used to link two concepts that are sufficiently similar that they can be used interchangeably in some information retrieval applications. In order to avoid the possibility of "compound errors" when combining mappings across more than two concept schemes, skos:closeMatch is not declared to be a transitive property.CommunityCommunity is a high-level concept that defines an online community and what it consists of.ContainerAn area in which content Items are contained.ForumA discussion area on which Posts or entries are made.ItemAn Item is something which can be in a Container.PostAn article or message that can be posted to a Forum.RoleA Role is a function of a User within a scope of a particular Forum, Site, etc.SpaceA Space is a place where data resides, e.g. on a website, desktop, fileshare, etc.SiteA Site can be the location of an online community or set of communities, with Users and Usergroups creating Items in a set of Containers. It can be thought of as a web-accessible data Space.ThreadA container for a series of threaded discussion Posts or Items.UserA User account in an online community site.UsergroupA set of User accounts whose owners have a common purpose or interest. Can be used for access control purposes.aboutSpecifies that this Item is about a particular resource, e.g. a Post describing a book, hotel, etc.account_ofRefers to the foaf:Agent or foaf:Person who owns this sioc:User online account.administrator_ofA Site that the User is an administrator of.attachmentThe URI of a file attached to an Item.avatarAn image or depiction used to represent this User.container_ofAn Item that this Container contains.contentThe content of the Item in plain text format.creator_ofA resource that the User is a creator of.Links to a previous (older) revision of this Item or Post.earlier_versionemailAn electronic mail address of the User.email_sha1An electronic mail address of the User, encoded using SHA1.feedA feed (e.g. RSS, Atom, etc.) pertaining to this resource (e.g. for a Forum, Site, User, etc.).followsIndicates that one User follows another User (e.g. for microblog posts or other content item updates).function_ofA User who has this Role.has_administratorA User who is an administrator of this Site.has_containerThe Container to which this Item belongs.has_creatorThis is the User who made this resource.has_functionA Role that this User has.has_hostThe Site that hosts this Forum.has_memberA User who is a member of this Usergroup.has_moderatorA User who is a moderator of this Forum.has_modifierA User who modified this Item.has_ownerA User that this resource is owned by.has_parentA Container or Forum that this Container or Forum is a child of.has_replyPoints to an Item or Post that is a reply or response to this Item or Post.has_scopeA resource that this Role applies to.has_spaceA data Space which this resource is a part of.has_subscriberA User who is subscribed to this Container.has_usergroupPoints to a Usergroup that has certain access to this Space.host_ofA Forum that is hosted on this Site.idAn identifier of a SIOC concept instance. For example, a user ID. Must be unique for instances of each type of SIOC concept within the same site.ip_addressThe IP address used when creating this Item. This can be associated with a creator. Some wiki articles list the IP addresses for the creator or modifiers when the usernames are absent.Links to a later (newer) revision of this Item or Post.later_versionLinks to the latest revision of this Item or Post.latest_versionlinkA URI of a document which contains this SIOC object.links_toLinks extracted from hyperlinks within a SIOC concept, e.g. Post or Site.member_ofA Usergroup that this User is a member of.moderator_ofA Forum that User is a moderator of.modifier_ofAn Item that this User has modified.nameThe name of a SIOC instance, e.g. a username for a User, group name for a Usergroup, etc.next_by_dateNext Item or Post in a given Container sorted by date.next_versionLinks to the next revision of this Item or Post.noteA note associated with this resource, for example, if it has been edited by a User.num_repliesThe number of replies that this Item, Thread, Post, etc. has. Useful for when the reply structure is absent.num_viewsThe number of times this Item, Thread, User profile, etc. has been viewed.owner_ofA resource owned by a particular User, for example, a weblog or image gallery.parent_ofA child Container or Forum that this Container or Forum is a parent of.previous_by_datePrevious Item or Post in a given Container sorted by date.previous_versionLinks to the previous revision of this Item or Post.related_toRelated Posts for this Post, perhaps determined implicitly from topics or references.reply_ofLinks to an Item or Post which this Item or Post is a reply to.scope_ofA Role that has a scope of this resource.siblingAn Item may have a sibling or a twin that exists in a different Container, but the siblings may differ in some small way (for example, language, category, etc.). The sibling of this Item should be self-describing (that is, it should contain all available information).space_ofA resource which belongs to this data Space.subscriber_ofA Container that a User is subscribed to.topicA topic of interest, linking to the appropriate URI, e.g. in the Open Directory Project or of a SKOS category.usergroup_ofA Space that the Usergroup has access to.Address BookDescribes a collection of personal or organisational addresses.Annotation SetDescribes a set of annotations, for example, those created by a particular user or related to a particular topic.Audio ChannelDescribes a channel for distributing audio or sound files, for example, a podcast.Bookmark FolderDescribes a shared collection of bookmarks.BriefcaseDescribes a briefcase or file service.Event CalendarDescribes a calendar of events.Image GalleryDescribes an image gallery, for example, a photo album.Project DirectoryDescribes a project directory.Resume BankDescribes a collection of resumes.Review AreaDescribes an area where reviews are posted.Subscription ListDescribes a shared set of feed subscriptions.Survey CollectionDescribes an area where survey data can be collected, e.g. from polls.Video ChannelDescribes a channel for distributing videos (moving image) files, for example, a video podcast.WikiDescribes a wiki space.Favourite ThingsDescribes a list or a collection of one's favourite things.Offer ListDescribes a list of the items someone has available to offer.PlaylistDescribes a list of media items that have been played or can be played.Reading ListDescribes a list of books or other materials that have been read or are suggested for reading.Wish ListDescribes a list of the items someone wishes to get.Argumentative DiscussionDescribes a discussion area where logical arguments can take place.Chat ChannelDescribes a channel for chat or instant messages, for example, via IRC or IM.Mailing ListDescribes an electronic mailing list.Message BoardDescribes a message board, also known as an online bulletin board or discussion forum.MicroblogDescribes a microblog, i.e. a blog consisting of short text messages.WeblogDescribes a weblog (blog), i.e. an online journal.PollDescribes a posted item that contains a poll or survey content.Blog PostDescribes a post that is specifically made on a weblog.Board PostDescribes a post that is specifically made on a message board.CommentComment is a subtype of sioc:Post and allows one to explicitly indicate that this SIOC post is a comment. Note that comments have a narrower scope than sioc:Post and may not apply to all types of community site.Instant MessageDescribes an instant message, e.g. sent via Jabber.Mail MessageDescribes an electronic mail message, e.g. a post sent to a mailing list.Microblog PostDescribes a post that is specifically made on a microblog.Wiki ArticleDescribes a wiki article.AnswerA Post that provides an answer in reply to a Question.Best AnswerA Post that is the best answer to a Question, as chosen by the User who asked the Question or as voted by a Community of Users.QuestionA Post that asks a Question.CategoryCategory is used on the object of sioc:topic to indicate that this resource is a category on a site.TagTag is used on the object of sioc:topic to indicate that this resource is a tag on a site.SpatialThingAnything with spatial extent, i.e. size, shape, or position. e.g. people, places, bowling balls, as well as abstract areas like cubes.
PointA point, typically described using a coordinate system relative to Earth, such as WGS84.
Uniquely identified by lat/long/alt. i.e.
spaciallyIntersects(P1, P2) :- lat(P1, LAT), long(P1, LONG), alt(P1, ALT),
lat(P2, LAT), long(P2, LONG), alt(P2, ALT).
sameThing(P1, P2) :- type(P1, Point), type(P2, Point), spaciallyIntersects(P1, P2).
latitudeThe WGS84 latitude of a SpatialThing (decimal degrees).longitudeThe WGS84 longitude of a SpatialThing (decimal degrees).altitudeThe WGS84 altitude of a SpatialThing (decimal meters
above the local reference ellipsoid).lat/longA comma-separated representation of a latitude, longitude coordinate.friend ofA person who shares mutual friendship with this person.acquaintance ofA person having more than slight or superficial knowledge of this person but short of friendship.parent ofA person who has given birth to or nurtured and raised this person.sibling ofA person having one or both parents in common with this person.child ofA person who was given birth to or nurtured and raised by this person.grandchild ofGrandchild OfA person who is a child of any of this person's children.spouse ofA person who is married to this personenemy ofA person towards whom this person feels hatred, intends injury to, or opposes the interests of.antagonist ofA person who opposes and contends against this person.ambivalent ofA person towards whom this person has mixed feelings or emotions.lost contact withA person who was once known by this person but has subsequently become uncontactable.knows ofA person who has come to be known to this person through their actions or position.would like to nowA person whom this person would desire to know more closely.knows in passingA person whom this person has slight or superficial knowledge of.knows by reputationA person known by this person primarily for a particular action, position or field of endeavour.close friend ofA person who shares a close mutual friendship with this person.has metA person who has met this person whether in passing or longer.works withA person who works for the same employer as this person.colleague ofA person who is a member of the same profession as this person.collaborates withA person who works towards a common goal with this person.employer ofA person who engages the services of this person.employed byA person for whom this person's services have been engaged.mentor ofA person who serves as a trusted counselor or teacher to this person.apprentice toA person to whom this person serves as a trusted counselor or teacher.lives withA person who shares a residence with this person.neighbor ofA person who lives in the same locality as this person.grandparent ofA person who is the parent of any of this person's parents.life partner ofA person who has made a long-term commitment to this person's.engaged toA person to whom this person is betrothed.ancestor ofA person who is a descendant of this person.Descendant Ofdescendant ofA person from whom this person is descended.participant inparticipantinfluenced bya person who has influenced this person.The object is a Tag which plays a role in the subject Tagging.associated tagtestingThe two tags are asserted to be equivalent --- that is, that whenever one is associated with a resource, the other tag can be logically inferred to also be associated. Be very careful with this. I'm not sure if this should be a subproperty of owl:sameAs.equivalent tagtestingIndicates that the subject tag applies to the object resource. This does not assert by who, when, or why the tagging occurred. For that information, use a reified Tagging resource.is tag ofThe name of a tag. Note that we can't relate this to skos:prefLabel because we cannot guarantee that tags have unique labels in a given conceptual scheme. Or can we?tag nameThe two tags are asserted as being related. This might be symmetric, but it certainly isn't transitive.related tagtestingThe relationship between a resource and a Tagging. Note, of course, that this allows us to tag tags and taggings themselves...tagThe name of a tag. Note that we can't relate this to skos:prefLabel because we cannot guarantee that tags have unique labels in a given conceptual scheme. Or can we? DEPRECATED 2005-05-19: redundant 'tag'.tag nameThe object plays the role of the tagger in the subject Tagging.tagged bytestingThe subject Tagging occurred at the subject time and date.tagged ontestingThe object is a resource which plays a role in the subject Tagging.tagged resourcetestingIndicates that the subject has been tagged with the object tag. This does not assert by who, when, or why the tagging occurred. For that information, use a reified Tagging resource.tagged with tag
================================================
FILE: application/config/application.ini
================================================
;;
; Zend application setup file
;
; Do not edit this file by hand unless you know what you are doing!
;;
[default]
; Bootstrap config
bootstrap.path = APPLICATION_PATH "Bootstrap.php"
bootstrap.class = "Bootstrap"
bootstrap.sessionVars[] = selectedResource
bootstrap.sessionVars[] = selectedModel
bootstrap.sessionVars[] = selectedClass
bootstrap.sessionVars[] = authResult
bootstrap.sessionVars[] = lastRoute
bootstrap.sessionVars[] = errorState
bootstrap.sessionVars[] = lastList
bootstrap.sessionVars[] = managedLists
; Resources
; resources.frontController.controllerDirectory = APPLICATION_PATH "controllers"
; Autoloader config
includePaths.libraries = ONTOWIKI_ROOT "libraries"
includePaths.classes = APPLICATION_PATH "classes"
autoloaderNamespaces.ontoWiki = "OntoWiki_"
autoloaderNamespaces.erfurt = "Erfurt_"
[unit_testing : default]
bootstrap.path = APPLICATION_PATH "classes/OntoWiki/Test/UnitTestBootstrap.php"
bootstrap.class = "OntoWiki_Test_UnitTestBootstrap"
[integration_testing : default]
bootstrap.path = APPLICATION_PATH "classes/OntoWiki/Test/IntegrationTestBootstrap.php"
bootstrap.class = "OntoWiki_Test_IntegrationTestBootstrap"
[extension_unit_testing : default]
bootstrap.path = APPLICATION_PATH "classes/OntoWiki/Test/ExtensionUnitTestBootstrap.php"
bootstrap.class = "OntoWiki_Test_ExtensionUnitTestBootstrap"
================================================
FILE: application/config/default.ini
================================================
;;
; OntoWiki main config file
;
; Host-specific options can be found in
; config.ini.
;
; @package application
; @subpackage config
; @copyright Copyright (c) 2008, {@link http://aksw.org AKSW}
; @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
;;
[default]
sysbase.model = "http://ns.ontowiki.net/SysBase/"
sysbase.path = "application/config/SysBase.rdf"
sysont.properties.hiddenImports = "http://ns.ontowiki.net/SysOnt/hiddenImports"
sysont.properties.hidden = "http://ns.ontowiki.net/SysOnt/hidden"
sysont.properties.isLarge = "http://ns.ontowiki.net/SysOnt/isLarge"
;;
; Main title prefix (head)
;;
title.prefix = "OntoWiki"
;;
; Main title separator (OntoWiki Class Instance)
;;
title.separator = " — "
;; Option for specifying the RSS/Atom feed loaded in the OntoWiki index actions "News" module
;; set to "false" to completely disable the feed
news.feedUrl = "http://blog.aksw.org/feed/?cat=5&client={{version.label}}&version={{version.number}}&suffix={{version.suffix}}"
;;
; Title Helper Configuration
; Properties to be searched for values with a human-readable
; string that represents a resource. The third part of the key has no
; meaning, just make sure to use a unique string. Numbers can cause your
; title properties to be overwritten when configs are merged.
;;
;; these are more important than rdfs:label
titleHelper.properties.skosPlabel = "http://www.w3.org/2004/02/skos/core#prefLabel"
titleHelper.properties.dcTitle = "http://purl.org/dc/elements/1.1/title"
titleHelper.properties.dcTitle2 = "http://purl.org/dc/terms/title"
titleHelper.properties.swrcTitle = "http://swrc.ontoware.org/ontology#title"
titleHelper.properties.foafName = "http://xmlns.com/foaf/0.1/name"
titleHelper.properties.doapName = "http://usefulinc.com/ns/doap#name"
titleHelper.properties.siocName = "http://rdfs.org/sioc/ns#name"
titleHelper.properties.tagName = "http://www.holygoat.co.uk/owl/redwood/0.1/tags/name"
titleHelper.properties.lgeodName = "http://linkedgeodata.org/vocabulary#name"
titleHelper.properties.geoName = "http://www.geonames.org/ontology#name"
titleHelper.properties.goName = "http://www.geneontology.org/dtds/go.dtd#name"
titleHelper.properties.rdfsLabel = "http://www.w3.org/2000/01/rdf-schema#label"
;; these are less important than rdfs:label ...
titleHelper.properties.accountName = "http://xmlns.com/foaf/0.1/accountName"
titleHelper.properties.foafNick = "http://xmlns.com/foaf/0.1/nick"
titleHelper.properties.foafSurname = "http://xmlns.com/foaf/0.1/surname"
titleHelper.properties.skosAlabel = "http://www.w3.org/2004/02/skos/core#altLabel"
;;
; Determines whether Title Helper prefers the property or the language
; when searching for title values.
;
; Possible values are "property" and "language"
;
; In property mode, the first value of a title property as defined in
; titleHelper.properties.* is used.
; In language mode, title helper searches through all title properties
; until it finds the best possible match to the requested language.
;;
titleHelper.searchMode = "language"
;;
; Always fall back to the local part of the URI for unknown resources.
;;
titleHelper.useLocalNames = true
;;
; Model Info description properties (maybe later a description helper?)
; Current usage is only /model/info/
;;
descriptionHelper.properties.rdfsComment = "http://www.w3.org/2000/01/rdf-schema#comment"
descriptionHelper.properties.dcDesc1 = "http://purl.org/dc/terms/description"
descriptionHelper.properties.dcDesc2 = "http://purl.org/dc/elements/1.1/description"
descriptionHelper.properties.skosNote = "http://www.w3.org/2004/02/skos/core#note"
descriptionHelper.properties.skosEditorialNote = "http://www.w3.org/2004/02/skos/core#editorialNote"
;;
; AC settings
;;
;ac.deactivateRegistration = true
;;
; List settings
;;
lists.showTypeColumnByDefault = "true"
;;
; Version info
;;
version.label = "OntoWiki"
version.number = "1.0.0"
version.suffix = ""
;;
; Help Menu URLs
;;
help.documentation = "http://docs.ontowiki.net"
help.issues = "https://github.com/AKSW/OntoWiki/issues"
help.versioninfo = "https://raw.github.com/AKSW/OntoWiki/master/debian/changelog"
;;
; Zend routes for built-in controllers
; Routes are applied in reverse order, so most specific routes should go last.
;;
; routes.linkeddata.route = "*"
; routes.linkeddata.defaults.controller = "ttt"
; routes.linkeddata.defaults.action = "ttt"
routes.default.route = ":controller/:action/*"
routes.default.defaults.action = "index"
routes.empty.route = ""
routes.empty.defaults.controller = "index"
routes.empty.defaults.action = "index"
routes.properties.route = "view/*"
routes.properties.defaults.controller = "resource"
routes.properties.defaults.action = "properties"
routes.instances.route = "list/*"
routes.instances.defaults.controller = "resource"
routes.instances.defaults.action = "instances"
routes.data.route = "data/*"
routes.data.defaults.controller = "resource"
routes.data.defaults.action = "export"
routes.sparql.route = "sparql/*"
routes.sparql.defaults.controller = "service"
routes.sparql.defaults.action = "sparql"
routes.update.route = "update/*"
routes.update.defaults.controller = "service"
routes.update.defaults.action = "update"
routes.search.route = "search/*"
routes.search.defaults.controller = "application"
routes.search.defaults.action = "search"
;routes.showsitemap.route = "sitemap.xml"
;routes.showsitemap.defaults.controller = "semanticsitemap"
;routes.showsitemap.defaults.action = "sitemap"
; Default route name
route.default.name = 'properties'
; Default index action if called action wasn't found
index.default.controller = "index"
index.default.action = "news"
;;
; HTML page encoding
;;
encoding = "utf-8"
;;
; Path for external libraries
;;
libraries.path = "libraries"
;;
; Default theme and themes folder
;;
themes.default = "silverblue"
themes.path = "extensions/themes"
;;
; Extension directories
;;
extensions.base = "extensions/"
extensions.legacy = "plugins/legacy/"
extensions.core[] = "application"
extensions.core[] = "account"
extensions.core[] = "exconf"
;;
; language options
;;
languages.locale = en
languages.path = "translations"
cache.translation = on
;;
; RDFa widget configuration
;;
update.endpoint = "endpoint"
;;
; Zend_Cache options
;;
cache.path = "cache"
cache.modules = off
;;
; Set this identifier to a unique value if you want to run multiple OntoWiki
; installations on one server
;;
;session.identifier = "abc123"
;;
; Disables certain inference features that make OntoWiki slow when used
; with large models (> 100.000 triples)
;;
system.inference = true
;;
; Web service configuration
;;
service.auth.allowGet = false
; Enables logging up to a certain level. The specified logs folder needs to
; be writable. To disable logging at all set this option to false. If the
; debug option is set to true logging is enabled (7) automatically.
;
; The following log levels are supported:
;
; 0: Emergency - System is unusable
; 1: Alert - Action must be taken immediately
; 2: Critical - Critical conditions
; 3: Error - Error conditions
; 4: Warning - Warning conditions
; 5: Notice - Normal but significant condition
; 6: Informational - Informational messages
; 7: Debug - Debug messages
;
log.enabled = true
log.level = 4
log.path = "logs"
;;
; Debug mode. Enables Debug outputs and logging
;;
; debug = true
;;
; Database setup. Please adjust these settings in
; config.ini.
;;
; store.backend = zenddb
; store.schema = rap
;
; store.zenddb.adapter = mysqli
; store.zenddb.host = localhost
; store.zenddb.username = owuser
; store.zenddb.password = owpass
; store.zenddb.dbname = ontowiki
;;
;;
; Some Erfurt Config Options
;;
;; Versioning switch
versioning = true
;; Erfurt Query Cache
cache.query.enable = false
;; logging is not recommended (performance)
;cache.query.logging = 0
;; only database caching at the moment
cache.query.type = database
;; Erfurt Object Cache
cache.enable = false ; clear the cache if you switch from 0 to 1!
cache.type = database ; database, sqllite
;; Options for cache frontend
cache.frontend.enable = false
cache.frontend.lifetime = 0
;cache.frontend.logging = false
;cache.frontend.write_control = true
;cache.frontend.automatic_cleaning_factor = 10
;cache.frontend.ignore_user_abort = false
cache.frontend.cache_id_prefix = 'OW_'
;; Cache backend options
;; Available: file | memcached | database | sqlite | apc
;; Recommended: memcached | file
cache.backend.type = "file"
;; Options for file cache backend
cache.backend.file.cache_dir = "./cache/"
cache.backend.file.file_locking = NULL
;; Options for memcached cache backend
;cache.backend.memcached.compression = false
;cache.backend.memcached.compatibility = false
;; You can define several servers: copy block, below and increase number and configure properly
cache.backend.memcached.servers.0.host = "localhost"
;cache.backend.memcached.servers.0.port = 11211
;cache.backend.memcached.servers.0.persistent = true
;cache.backend.memcached.servers.0.weight = 1
;cache.backend.memcached.servers.0.timeout = 5
;cache.backend.memcached.servers.0.retry_interval = 15
;cache.backend.memcached.servers.0.status = 15
;; Options for sqlite cache backend
cache.backend.sqlite.cache_db_complete_path = "/tmp/ow_cache.sqlite"
;cache.backend.sqlite.automatic_vacuum_factor = 10
;; Options for worker
worker.enable = false
worker.backend = "Gearman"
worker.servers = "localhost:4730"
;; Virtual host configurations (optional, e.g. when OntoWiki is reachable via multiple domains)
;vhosts[] = "http://graph1.ontowiki.de"
;vhosts[] = "http://graph2.ontowiki.de"
================================================
FILE: application/config/default.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :ontowiki .
:ontowiki a doap:Project ;
owconfig:privateNamespace ;
:encoding "utf-8" ;
:versioning "true"^^xsd:boolean ;
owconfig:hasModule :Default .
:Default a owconfig:Module ;
rdfs:label "OntoWiki" ;
rdfs:label " — " .
:ontowiki doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: application/controllers/ApplicationController.php
================================================
* @author Philipp Frischmuth
*/
class ApplicationController extends OntoWiki_Controller_Base
{
/**
* Displays OntoWiki's about page
*/
public function aboutAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->view->placeholder('main.window.title')
->set('About ' . $this->_config->version->label);
$version = $this->_config->version->number;
if (isset($this->_config->version->suffix)) {
$version .= ' ' . $this->_config->version->suffix;
}
if (is_writable($this->_config->cache->path)) {
$cacheWritable = ' (writable)';
} else {
$cacheWritable = ' (not writable!)';
}
if (is_writable($this->_config->log->path)) {
$logWritable = ' (writable)';
} else {
$logWritable = ' (not writable!)';
}
$cacheBackend = $this->_config->cache->backend->type;
$cacheBackendOptions = array();
$cacheFrontendOptions = array();
foreach ($this->_config->cache->frontend->toArray() as $key => $value) {
$cacheFrontendOptions[] = $key.": ".(string)$value;
}
if (isset($this->_config->cache->backend->$cacheBackend)) {
foreach ($this->_config->cache->backend->$cacheBackend->toArray() as $key => $value) {
$cacheBackendOptions[] = $key.": ".(string)$value;
}
}
$cacheFrontendOptions = join(", ", $cacheFrontendOptions);
$cacheBackendOptions = join(", ", $cacheBackendOptions);
$data = array(
'System' => array(
'Release' => $version,
'PHP Version' => phpversion(),
'Backend' => $this->_owApp->erfurt->getStore()->getBackendName(),
'Debug Mode' => defined('_OWDEBUG') ? 'enabled' : 'disabled'
),
'User Interface' => array(
'Theme' => rtrim($this->_config->themes->default, '/'),
'Language' => $this->_config->languages->locale,
),
'Paths' => array(
'Extensions Path' => _OWROOT . rtrim($this->_config->extensions->base, '/'),
'Translations Path' => _OWROOT . rtrim($this->_config->languages->path, '/'),
'Themes Path' => _OWROOT . rtrim($this->_config->themes->path, '/'),
'Temporary Directory' => Erfurt_App::getInstance()->getTmpDir()
),
'Cache' => array(
'State' => $this->_config->cache->frontend->enable ? 'enabled' : 'disabled',
'Frontend Options' => $cacheFrontendOptions,
'Backend' => $cacheBackend,
'Backend Options' => $cacheBackendOptions,
// 'Path' => rtrim($this->_config->cache->path, '/') . $cacheWritable,
'Module Caching' => ((bool)$this->_config->cache->modules == true) ? 'enabled' : 'disabled',
'Translation Caching' => ((bool)$this->_config->cache->translation == true) ? 'enabled' : 'disabled'
),
'Logging' => array(
'Path' => rtrim($this->_config->log->path, '/') . $logWritable,
'Status' => (bool)$this->_config->log->enabled ? 'enabled' : 'disabled',
'Level' => (int)$this->_config->log->level
)
);
// check if the git comand exists and ontowiki is a working directory
if (file_exists('.git') && substr(@exec('git --version'), 0, 11) == 'git version') {
$data['Git Versioning'] = array(
'Version' => @exec('git describe'),
'Branch' => @exec('git rev-parse --abbrev-ref HEAD'),
'last commit' => @exec("git log --pretty=format:'%ar' -n 1")
);
}
$this->view->data = $data;
}
/**
* Authenticates with Erfurt using the provided credentials.
*/
public function loginAction()
{
$erfurt = $this->_owApp->erfurt;
$post = $this->_request->getPost();
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
// If remember option is on make session persistent
if (!empty($post['login-save']) && $post['login-save'] == 'on') {
// Make session persistent (for about 23 years)
Zend_Session::rememberMe(726364800);
}
$loginType = $post['logintype'];
// lokaler Login
if ($loginType === 'locallogin') {
$username = $post['username'];
$password = $post['password'];
$authResult = $erfurt->authenticate($username, $password);
} else {
if ($loginType === 'openidlogin') {
// OpenID
$username = $post['openid_url'];
$redirectUrl = $post['redirect-uri'];
$verifyUrl = $this->_config->urlBase . 'application/verifyopenid';
$authResult = $erfurt->authenticateWithOpenId($username, $verifyUrl, $redirectUrl);
} else {
if ($loginType === 'webidlogin') {
// FOAF+SSL
$redirectUrl = $this->_config->urlBase . 'application/loginfoafssl';
$authResult = $erfurt->authenticateWithFoafSsl(null, $redirectUrl);
} else {
// Not supported...
return;
}
}
}
// reload selected model w/ new privileges
if ($this->_owApp->selectedModel instanceof Erfurt_Rdf_Model) {
$this->_owApp->selectedModel = $erfurt->getStore()->getModel((string)$this->_owApp->selectedModel);
}
$this->_owApp->authResult = $authResult->getMessages();
}
public function verifyopenidAction()
{
$erfurt = $this->_owApp->erfurt;
$get = $this->_request->getQuery();
$authResult = $erfurt->verifyOpenIdResult($get);
$this->_owApp->authResult = $authResult->getMessages();
if (isset($get['ow_redirect_url'])) {
$this->_redirect(urldecode($get['ow_redirect_url']), array('prependBase' => false));
} else {
$this->_redirect($this->_config->urlBase, array('prependBase' => false));
}
}
public function loginfoafsslAction()
{
$erfurt = $this->_owApp->erfurt;
$get = $this->_request->getQuery();
$authResult = $erfurt->authenticateWithFoafSsl($get);
$this->_owApp->authResult = $authResult->getMessages();
$this->_redirect($this->_config->urlBase, array('prependBase' => false));
}
/**
* Destroys auth credentials and logs the current agent out.
*/
public function logoutAction()
{
// destroy auth
Erfurt_Auth::getInstance()->clearIdentity();
// destroy any selections user has made
Zend_Session::destroy(true);
$this->_redirect($this->_config->urlBase);
}
/**
* Registers a new user
*/
public function registerAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
//check if the Register Action is allowed
if (isset($this->_owApp->config->ac)
&& ((boolean)$this->_owApp->config->ac->deactivateRegistration === true)
) {
$this->_helper->viewRenderer->setNoRender();
$this->view->placeholder('main.window.title')->set('Register User');
$message = 'The registration is deactivated, please consult an Admin about this.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
return;
}
$this->_helper->viewRenderer->setScriptAction('register');
$this->view->placeholder('main.window.title')->set('Register User');
$this->view->formActionUrl = $this->_config->urlBase . 'application/register';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'registeruser';
$this->view->username = '';
$this->view->readonly = '';
$this->view->email = '';
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Register User'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Reset Form'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
$post = $this->_request->getPost();
$this->_owApp->appendMessage(
new OntoWiki_Message(
'Already own an OpenID?Register here',
OntoWiki_Message::INFO,
array('escape' => false, 'translate' => false)
)
);
$contentType = $this->_request->getHeader('Content-Type');
if (strstr($contentType, 'application/json')) {
$rawBody = $this->_request->getRawBody();
echo $rawBody;
$post = Zend_Json::decode($rawBody);
}
if ($post) {
/* status var in order to fire corresponding events */
$registrationError = true;
$registeredUsernames = array();
$registeredEmailAddresses = array();
foreach ($this->_erfurt->getUsers() as $userUri => $userArray) {
if (array_key_exists('userName', $userArray)) {
$registeredUsernames[] = $userArray['userName'];
}
if (array_key_exists('userEmail', $userArray)) {
$registeredEmailAddresses[] = str_replace('mailto:', '', $userArray['userEmail']);
}
}
$email = $post['email'];
$this->view->email = $email;
$username = $post['username'];
$this->view->username = $username;
$password = $post['password'];
$passwordTwo = $post['password2'];
$emailValidator = new Zend_Validate_EmailAddress();
if (!$this->_erfurt->isActionAllowed('RegisterNewUser')
|| !($actionConfig = $this->_erfurt->getActionConfig('RegisterNewUser'))
) {
$message = 'Action not permitted for the current user.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (trim($email) == '') {
$message = 'Email address must not be empty.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (in_array($email, $registeredEmailAddresses)) {
$message = 'Email address is already registered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
if (isset($actionConfig['mailvalidation'])
&& $actionConfig['mailvalidation'] == 'yes'
&& !$emailValidator->isValid($email)
) {
$message = 'Email address validation failed.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
if (in_array($username, $registeredUsernames)
|| ($username == $this->_owApp->erfurt->getStore()->getDbUser())
) {
$message = 'Username already registered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
if (isset($actionConfig['uidregexp'])
&& !preg_match($actionConfig['uidregexp'], $username)
) {
$message = 'Username contains illegal characters.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
if ($password !== $passwordTwo) {
$message = 'Passwords do not match.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
if (strlen($password) < 5) {
$message = 'Password needs at least 5 characters.';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::ERROR)
);
} else {
if (isset($actionConfig['passregexp'])
&& $actionConfig['passregexp'] != ''
&& !@preg_match($actionConfig['passregexp'], $password)
) {
$message
= 'Password does not match regular expression set in system configuration';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::ERROR)
);
} else {
// give default group?
if (isset($actionConfig['defaultGroup'])) {
$group = $actionConfig['defaultGroup'];
}
// add new user
if ($this->_erfurt->addUser($username, $password, $email, $group)) {
$message = 'The user "' . $username . '" has been successfully registered.';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::SUCCESS)
);
$registrationError = false;
} else {
$message = 'A registration error occured. Please refer to the log entries.';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::ERROR)
);
}
}
}
}
}
}
}
}
/*
* fire events for success and error
*/
if ($registrationError === false) {
$event = new Erfurt_Event('onRegisterUser');
$event->username = $username;
$event->response = $this->_response;
$event->trigger();
} else {
$event = new Erfurt_Event('onRegisterUserFailed');
$event->username = $username;
$event->message = $message;
$event->response = $this->_response;
$event->trigger();
}
}
}
/**
* Registers a new user with a given OpenID.
*/
public function openidregAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
//check if the Register Action is allowed
if (isset($this->_owApp->config->ac)
&& ((boolean)$this->_owApp->config->ac->deactivateRegistration === true)
) {
$this->_helper->viewRenderer->setNoRender();
$this->view->placeholder('main.window.title')->set('Register User');
$message = 'The registration is deactivated, please consult an Admin about this.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
return;
}
// We render a template, that is also used for preferences.
$this->_helper->viewRenderer->setScriptAction('openid');
$this->view->placeholder('main.window.title')->set('Register User with OpenID');
$this->view->formActionUrl = $this->_config->urlBase . 'application/openidreg';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'registeruser';
// Fetch POST and GET of the request. One of them or both will be empty.
$post = $this->_request->getPost();
$get = $this->_request->getQuery();
if (!empty($post)) {
// Step 1: User entered data and clicked on 'Check OpenID'
if ((int)$post['step'] === 1) {
$openId = $post['openid_url'];
$label = $post['label'];
$email = $post['email'];
$emailValidator = new Zend_Validate_EmailAddress();
// Is register action allowed for current user?
if (!$this->_erfurt->isActionAllowed('RegisterNewUser')
|| !($actionConfig = $this->_erfurt->getActionConfig('RegisterNewUser'))
) {
$message = 'Action not permitted for the current user.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (empty($openId)) {
// openid_url field must not be empty
$message = 'No OpenID was entered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (array_key_exists($openId, $this->_erfurt->getUsers())) {
// Does user already exist?
$message = 'A user with the given OpenID is already registered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (!empty($email)
&& isset($actionConfig['mailvalidation'])
&& $actionConfig['mailvalidation'] === 'yes'
&& !$emailValidator->isValid($email)
) {
// If an (optional) email address is given, check whether it is valid.
$message = 'Email address validation failed.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
// Everything seems to be OK... Check the OpenID (redirect to the provider).
// We want to verify the OpenID auth response in this action.
$verifyUrl = $this->_config->urlBase . 'application/openidreg';
// If label and/or email are given, put them at the end of the request url, for
// we need them later.
if (!empty($label) && !empty($email)) {
$verifyUrl .= '?label=' . urlencode($label) . '&email=' . urlencode($email);
} else if (!empty($label)) {
$verifyUrl .= '?label=' . urlencode($label);
} else if (!empty($email)) {
$verifyUrl .= '?email=' . urlencode($email);
}
$sReg = new Zend_OpenId_Extension_Sreg(
array(
'nickname' => false,
'email' => false),
null,
1.1
);
$adapter = new Erfurt_Auth_Adapter_OpenId($openId, $verifyUrl, null, null, $sReg);
// We use the adapter directly, for we do not store the identity in session.
$result = $adapter->authenticate();
// If we reach this point, something went wrong
$message = 'OpenID check failed.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
}
// If we reach this section, something went wrong, so we reset the form and show the message.
$this->view->openid = '';
$this->view->readonly = '';
$this->view->email = '';
$this->view->label = '';
$this->view->step = 1;
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Check OpenID'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Reset Form'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
} else if ((int)$post['step'] === 2) {
// Step 2: OpenID was verified and user clicked on register button.
$openid = $post['openid_url'];
$email = $post['email'];
$label = $post['label'];
// Give user default group?
$actionConfig = $this->_erfurt->getActionConfig('RegisterNewUser');
$group = null;
if (isset($actionConfig['defaultGroup'])) {
$group = $actionConfig['defaultGroup'];
}
// Add the new user.
if ($this->_erfurt->addOpenIdUser($openid, $email, $label, $group)) {
$message = 'The user with the OpenID "' . $openid . '" has been successfully registered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::SUCCESS));
} else {
$message = 'A registration error occured. Please refer to the log entries.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
}
// Reset the form...
$this->view->openid = '';
$this->view->readonly = '';
$this->view->email = '';
$this->view->label = '';
$this->view->step = 1;
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Check OpenID'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Reset Form'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
} else if (!empty($get)) {
// This is the verify request
$sReg = new Zend_OpenId_Extension_Sreg(
array(
'nickname' => false,
'email' => false),
null,
1.1
);
$adapter = new Erfurt_Auth_Adapter_OpenId(null, null, null, $get, $sReg);
// We use the adapter directly, for we do not store the identity in session.
$result = $adapter->authenticate();
if (!$result->isValid()) {
// Something went wrong, show a message
$message = 'OpenID verification failed.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
}
$data = $sReg->getProperties();
// Use the prefilled data from the user (if given) or if not use the data from the provider (if
// available).
if (isset($get['email'])) {
$email = $get['email'];
} else if (isset($data['email'])) {
$email = $data['email'];
} else {
$email = '';
}
if (isset($get['label'])) {
$label = $get['label'];
} else if (isset($data['nickname'])) {
$label = $data['nickname'];
} else {
$label = '';
}
$this->view->openid = $get['openid_identity'];
$this->view->readonly = 'readonly="readonly"'; // OpenID must not be changed now.
$this->view->email = $email;
$this->view->label = $label;
$this->view->step = 2;
$this->view->checked = true; // We use this to show a green icon for success
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Register User'))
->appendButton(OntoWiki_Toolbar::CANCEL, array('name' => 'Cancel', 'class' => 'openidreg-cancel'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
} else {
// No post and get data... This is the initial form...
$this->view->openid = '';
$this->view->readonly = '';
$this->view->email = '';
$this->view->label = '';
$this->view->step = 1;
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Check OpenID'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Reset Form'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
}
public function webidregAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
//check if the Register Action is allowed
if (isset($this->_owApp->config->ac)
&& ((boolean)$this->_owApp->config->ac->deactivateRegistration === true)
) {
$this->_helper->viewRenderer->setNoRender();
$this->view->placeholder('main.window.title')->set('Register User');
$message = 'The registration is deactivated, please consult an Admin about this.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
return;
}
// We render a template, that is also used for preferences.
$this->_helper->viewRenderer->setScriptAction('webid');
$this->view->placeholder('main.window.title')->set('Register User with FOAF+SSL');
$this->view->formActionUrl = $this->_config->urlBase . 'application/webidreg';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'registeruser';
// Fetch POST and GET of the request. One of them or both will be empty.
$post = $this->_request->getPost();
$get = $this->_request->getQuery();
// Step 1: Fetch the WebID...
if (empty($post) && empty($get)) {
$redirectUrl = $this->_config->urlBase . 'application/webidreg';
$adapter = new Erfurt_Auth_Adapter_FoafSsl(null, $redirectUrl);
$webId = $adapter->fetchWebId();
// We should not reach this point;
return;
} else if (!empty($get)) {
// Step 2: Check the web id and fetch foaf data
$get['url'] = $this->_request->getRequestUri();
$adapter = new Erfurt_Auth_Adapter_FoafSsl();
try {
$valid = $adapter->verifyIdpResult($get);
if ($valid) {
$webId = $get['webid'];
$foafData = Erfurt_Auth_Adapter_FoafSsl::getFoafData($webId);
if ($foafData !== false) {
// Try to get a mbox and label...
if (isset($foafData[$webId]['http://xmlns.com/foaf/0.1/mbox'])) {
$email = $foafData[$webId]['http://xmlns.com/foaf/0.1/mbox'][0]['value'];
} else {
$email = '';
}
if (isset($foafData[$webId][EF_RDFS_LABEL])) {
$label = $foafData[$webId][EF_RDFS_LABEL][0]['value'];
} else {
$label = '';
}
} else {
$email = '';
$label = '';
}
$this->view->webid = $webId;
if ($webId != '') {
$this->view->checked = true;
}
if (null !== $email) {
$this->view->email = $email;
} else {
$this->view->email = '';
}
if (null !== $label) {
$this->view->label = $label;
} else {
$this->view->label = '';
}
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Register'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
return;
} else {
// TODO Error message
$this->view->webid = '';
$this->view->email = '';
$this->view->label = '';
$this->_owApp->appendMessage(
new OntoWiki_Message('No valid certificate found.', OntoWiki_Message::ERROR)
);
return;
}
} catch (Exception $e) {
$this->view->webid = '';
$this->view->email = '';
$this->view->label = '';
$this->_owApp->appendMessage(
new OntoWiki_Message('Something went wrong: ' . $e->getMessage(), OntoWiki_Message::ERROR)
);
return;
}
} else if (!empty($post)) {
$webId = $post['webid_url'];
$label = $post['label'];
$email = $post['email'];
$emailValidator = new Zend_Validate_EmailAddress();
// Is register action allowed for current user?
if (!$this->_erfurt->isActionAllowed('RegisterNewUser')
|| !($actionConfig = $this->_erfurt->getActionConfig('RegisterNewUser'))
) {
$message = 'Action not permitted for the current user.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (empty($webId)) {
// openid_url field must not be empty
$message = 'No WebID was entered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (array_key_exists($webId, $this->_erfurt->getUsers())) {
// Does user already exist?
$message = 'A user with the given WebID is already registered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else if (!empty($email)
&& isset($actionConfig['mailvalidation'])
&& $actionConfig['mailvalidation'] === 'yes'
&& !$emailValidator->isValid($email)
) {
// If an (optional) email address is given, check whether it is valid.
$message = 'Email address validation failed.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
} else {
// Everything seems to be OK...
$actionConfig = $this->_erfurt->getActionConfig('RegisterNewUser');
$group = null;
if (isset($actionConfig['defaultGroup'])) {
$group = $actionConfig['defaultGroup'];
}
// Add the new user.
if ($this->_erfurt->addOpenIdUser($webId, $email, $label, $group)) {
$message = 'The user with the WebID "' . $webId . '" has been successfully registered.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::SUCCESS));
} else {
$message = 'A registration error occured. Please refer to the log entries.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
}
}
// If we reach this section, something went wrong, so we reset the form and show the message.
$this->view->webid = '';
$this->view->email = '';
$this->view->label = '';
}
}
/**
* Edits user preferences
*/
public function preferencesAction()
{
$this->view->placeholder('main.window.title')->set('User Preferences');
$this->addModuleContext('main.window.preferences');
$user = $this->_owApp->getUser();
// Anonymous and Db-User have no prefs.
if ($user->isAnonymousUser() || $user->isDbUser()) {
$this->_redirect($this->_config->urlBase, array('prependBase' => false));
}
$post = $this->_request->getPost();
if ($post) {
// We catch all exceptions here, for we do not want the user to see ow crash if something unexpected
// happens.
try {
if (isset($post['openid'])) {
$this->_updateOpenIdUser($post);
} else {
$this->_updateUser($post);
}
} catch (Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message('Something went wrong: ' . $e->getMessage(), OntoWiki_Message::ERROR)
);
}
if (!$this->_owApp->hasMessages()) {
$message = 'Changes saved.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::SUCCESS));
}
}
$this->view->isOpenIdUser = ($user->isOpenId() || $user->isWebId());
if ($user->isOpenId() || $user->isWebId()) {
$this->view->openid = $user->getUri();
$usernameReadonly = '';
} else {
$usernameReadonly = 'readonly="readonly"';
}
$email = $user->getEmail();
if (substr($email, 0, 7) === 'mailto:') {
$email = substr($email, 7);
}
$username = $user->getUsername();
$this->view->formActionUrl = $this->_config->urlBase . 'application/preferences';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'registeruser';
$this->view->username = $username;
$this->view->userReadonly = $usernameReadonly;
$this->view->email = $email;
$this->view->submitText = 'Save Changes';
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Save Changes', 'id' => 'registeruser'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Reset Form'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->_helper->viewRenderer->setScriptAction('userdetails');
}
protected function _updateEmailAddress($newEmail)
{
try {
$this->_erfurt->getAuth()->setEmail($newEmail);
} catch (Erfurt_Auth_Identity_Exception $e) {
$this->_owApp->appendMessage(new OntoWiki_Message($e->getMessage(), OntoWiki_Message::ERROR));
return false;
}
return true;
}
protected function _updateUsername($newUsername)
{
try {
$this->_erfurt->getAuth()->setUsername($newUsername);
} catch (Erfurt_Auth_Identity_Exception $e) {
$this->_owApp->appendMessage(new OntoWiki_Message($e->getMessage(), OntoWiki_Message::ERROR));
return false;
}
return true;
}
protected function _updatePassword($passwordOne, $passwordTwo)
{
if ($passwordOne !== $passwordTwo) {
$message = 'Passwords do not match.';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::ERROR));
return false;
}
try {
$this->_erfurt->getAuth()->getIdentity()->setPassword($passwordOne);
} catch (Erfurt_Auth_Identity_Exception $e) {
$this->_owApp->appendMessage(new OntoWiki_Message($e->getMessage(), OntoWiki_Message::ERROR));
return false;
}
return true;
}
protected function _updateOpenIdUser($post)
{
if ($this->_updateUsername($post['username'])) {
if ($this->_updateEmailAddress($post['email'])) {
if (isset($post['changepassword']) && $post['changepassword'] === '1') {
return $this->_updatePassword($post['password1'], $post['password2']);
} else {
return true;
}
}
}
return false;
}
protected function _updateUser($post)
{
if ($this->_updateEmailAddress($post['email'])) {
if (isset($post['changepassword']) && $post['changepassword'] === '1') {
return $this->_updatePassword($post['password1'], $post['password2']);
} else {
return true;
}
}
return false;
}
/**
* Handles search requests
*/
public function searchAction()
{
$title = $this->_owApp->translate->_('Resource Search');
$this->view->placeholder('main.window.title')->set($title);
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$store = $this->_erfurt->getStore();
if (isset($this->_owApp->selectedModel) && null !== $this->_owApp->selectedModel) {
$modelUri = $this->_owApp->selectedModel->getModelIri();
} else {
$modelUri = null;
}
if ($this->_request->getParam('searchtext-input') !== null) {
$searchText = trim($this->getParam('searchtext-input'));
}
$error = false;
$errorMsg = '';
// check if search is already errorenous
if (!$error) {
// try sparql query pre search check (with limit to 1)
$elements = $store->getSearchPattern($searchText, $modelUri);
$query = new Erfurt_Sparql_Query2();
$query->addElements($elements);
$query->setLimit(1);
$query->addFrom($modelUri);
try {
$store->sparqlQuery($query);
} catch (Exception $e) {
// build error message
$this->_owApp->appendMessage(
new OntoWiki_Message(
$this->_owApp->translate->_('search failed'),
OntoWiki_Message::ERROR
)
);
$error = true;
$errorMsg .= 'Message details: ';
$errorMsg .= str_replace('LIMIT 1', '', $e->getMessage());
}
}
// if error occured set output for error page
if ($error) {
$this->view->errorMsg = $errorMsg;
} else {
// set redirect to effective search controller
$url = new OntoWiki_Url(array('controller' => 'list'), array());
$url->setParam('s', $searchText);
$url->setParam('init', '1');
$this->_redirect($url);
}
}
}
================================================
FILE: application/controllers/DebugController.php
================================================
*/
class DebugController extends OntoWiki_Controller_Base
{
/**
* Clears the module cache
*
* @return void
*/
public function clearmodulecacheAction()
{
$this->view->clearModuleCache();
$this->_redirect($_SERVER['HTTP_REFERER'], array('code' => 302));
}
/**
* Clears the translation cache
*
* @return void
*/
public function cleartranslationcacheAction()
{
if (Zend_Translate::hasCache()) {
Zend_Translate::clearCache();
}
$this->_redirect($_SERVER['HTTP_REFERER'], array('code' => 302));
}
/**
* Destroys the current session
*
* @return void
*/
public function destroysessionAction()
{
Zend_Session::destroy(true);
$this->_redirect($this->_config->urlBase);
}
/**
* Destroys complete query cache and object cache
*
* @return void
*/
public function clearquerycacheAction()
{
$queryCache = $this->_erfurt->getQueryCache();
$queryCacheReturnValue = $queryCache->cleanUpCache(array('mode' => 'uninstall'));
$objectCache = $this->_erfurt->getCache();
$objectCacheReturnValue = $objectCache->clean();
$this->_redirect($_SERVER['HTTP_REFERER'], array('code' => 302));
}
}
================================================
FILE: application/controllers/ErrorController.php
================================================
*/
class ErrorController extends Zend_Controller_Action
{
/**
* OntoWiki Application
*
* @var OntoWiki
*/
protected $_owApp = null;
/**
* OntoWiki Application config
*
* @var Zend_Config
*/
protected $_config = null;
/**
* The session store
*
* @var Zend_Session
*/
protected $_session = null;
/**
* Erfurt App
*
* @var Erfurt_App
*/
protected $_erfurt = null;
/**
* Constructor
*/
public function init()
{
// init controller variables
$this->_owApp = OntoWiki::getInstance();
$this->_config = $this->_owApp->config;
$this->_session = $this->_owApp->session;
$this->_erfurt = $this->_owApp->erfurt;
}
/**
* Default action that is triggered when an error occures
* during the dispatch process.
*/
public function errorAction()
{
if (defined('_OWDEBUG')) {
$this->_debugError();
} else {
$this->_gracefulError();
}
// we provide a complete page
$this->_helper->layout()->disableLayout();
}
/*
* the debug error output has a stacktrace and other debug information
*/
protected function _debugError()
{
if ($this->_request->has('error_handler')) {
// get errors passed by error handler plug-in
$errors = $this->_getParam('error_handler');
$exception = $errors->exception;
// check error type and send headers accordingly
switch ($errors->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
$this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
break;
default:
// don't change headers
}
switch (true) {
case ($exception instanceof OntoWiki_Http_Exception):
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$response = $this->getResponse();
$response->setHttpResponseCode($exception->getResponseCode());
$response->setBody($exception->getResponseMessage());
return;
}
// exception code determines whether error or info
// see erfurt developer documentation
if (($exception->getCode() > 0) && ($exception->getCode() < 2000)) {
$this->view->heading = 'OntoWiki Info Notice';
$this->view->errorType = 'info';
$this->view->code = $exception->getCode();
} else {
$this->view->heading = 'OntoWiki Error';
$this->view->errorType = 'error';
if ($exception->getCode() !== 0) {
$this->view->code = $exception->getCode();
}
$response = $this->getResponse();
$response->setHttpResponseCode(500);
}
$errorString = $exception->getMessage();
$this->view->exceptionType = get_class($exception);
$this->view->exceptionFile = $exception->getFile() . '@' . $exception->getLine();
$stacktrace = $exception->getTrace();
$stacktraceString = '';
foreach ($stacktrace as $i => $spec) {
$lineStr = '';
if (isset($spec['file'])) {
$lineStr = '@' . $spec['file'];
if (isset($spec['line'])) {
$lineStr .= ':' . $spec['line'];
}
}
$stacktraceString .= '#' . $i . ': ' . (isset($spec['class']) ? $spec['class'] : '') .
(isset($spec['type']) ? $spec['type'] : '') . $spec['function'] .
$lineStr . ' ';
}
$this->view->stacktrace = $stacktraceString;
} else {
$this->view->heading = 'OntoWiki Error';
$this->view->errorType = 'error';
$message = current(OntoWiki::getInstance()->drawMessages());
if ($message instanceof OntoWiki_Message) {
$errorString = $message->getText();
} else {
// No message, redirect to index page
$this->_redirect($this->config->urlBase, array('code' => 302));
}
}
$this->view->urlBase = $this->_config->urlBase;
$this->view->errorText = $errorString;
}
/*
* the graceful error output tries to be as nice as possible
*/
protected function _gracefulError()
{
$requestExtra = str_replace(
$this->getRequest()->getBaseUrl(),
'',
$this->getRequest()->getRequestUri()
);
$requestedUri = OntoWiki::getInstance()->config->urlBase . ltrim($requestExtra, '/');
$createUrl = new OntoWiki_Url(array(), array());
$createUrl->controller = 'resource';
$createUrl->action = 'new';
$createUrl->setParam('r', $requestedUri);
$this->view->requestedUrl = (string)$requestedUri;
$this->view->createUrl = (string)$createUrl;
$this->view->urlBase = OntoWiki::getInstance()->config->urlBase;
$exception = null;
$exceptionType = null;
if ($this->_request->has('error_handler')) {
// get errors passed by error handler plug-in
$errors = $this->_getParam('error_handler');
$exception = $errors->exception;
$exceptionType = get_class($exception);
$errorString = $exception->getMessage();
OntoWiki::getInstance()->logger->emerg(
$exceptionType . ': ' . $errorString . ' -> ' .
$exception->getFile() . '@' . $exception->getLine()
);
}
// Zend_Controller_Dispatcher_Exception means invalid controller
// -> resource not found
if (($this->_request->has('error_handler'))
&& ($exceptionType != 'Zend_Controller_Dispatcher_Exception')
) {
if ((null !== $exception)
&& (method_exists($exception, 'getResponseCode'))
&& (null !== $exception->getResponseCode())
) {
$this->getResponse()->setHttpResponseCode($exception->getResponseCode());
$this->_helper->viewRenderer->setScriptAction('error');
} else {
$this->getResponse()->setHttpResponseCode(500);
$this->_helper->viewRenderer->setScriptAction('500');
}
} else {
$this->getResponse()->setHttpResponseCode(404);
$this->_helper->viewRenderer->setScriptAction('404');
}
}
}
================================================
FILE: application/controllers/IndexController.php
================================================
*/
class IndexController extends OntoWiki_Controller_Base
{
/**
* Timeout for reading the OntoWiki RSS news feed.
*/
const NEWS_FEED_TIMEOUT_IN_SECONDS = 3;
/**
* Displays the OntoWiki news feed short summary (dashboard part)
*/
public function newsshortAction()
{
// requires zend Feed module
// number of news
$feedCount = 3;
$owFeed = $this->getNews();
// create new array for data
$data = array();
// parse feed items into array
foreach ($owFeed as $feedItem) {
// form temporary array with needed data
$description = substr($feedItem->description(), 0, strpos($feedItem->description(), ' ', 40)) . ' [...]';
$tempdata = array(
'link' => $feedItem->link(),
'title' => $feedItem->title(),
'description' => $description
);
// append temporary array to data array
$data[] = $tempdata;
// take only needed items
if (count($data) == $feedCount) {
break;
}
}
// assign data array to view rss data variable
$this->view->rssData = $data;
}
/**
* Displays messages only without any other content.
*/
public function messagesAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->view->placeholder('main.window.title')->set('OntoWiki Messages');
$this->_helper->viewRenderer->setNoRender();
}
/**
* Displays the OntoWiki news feed
*/
public function newsAction()
{
$this->view->placeholder('main.window.title')->set('News');
$owFeed = $this->getNews();
$this->view->feed = $owFeed;
if ($owFeed instanceof Zend_Feed_Abstract) {
$this->view->title = $owFeed->title();
$this->view->link = $owFeed->link();
$this->view->description = $owFeed->description();
}
OntoWiki::getInstance()->getNavigation()->disableNavigation();
}
/**
* Default action if called action wasn't found
*/
public function __call($action, $params)
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->view->placeholder('main.window.title')->set('Welcome to OntoWiki');
if ($this->_owApp->hasMessages()) {
$this->_forward('messages', 'index');
} else {
if (!isset($this->_config->index->default->controller)
|| !isset($this->_config->index->default->action)
) {
$this->_forward('news', 'index');
} else {
$this->_forward($this->_config->index->default->action, $this->_config->index->default->controller);
}
}
}
/**
* This action display simply no main window section and is useful
* in combination with index.default.controller and index.default.action
*/
public function emptyAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
OntoWiki::getInstance()->getNavigation()->disableNavigation();
// sorry for this hack, but I dont wanted to modify the the main layout too much ...
$this->view->placeholder('main.window.additionalclasses')->set('hidden');
}
/**
* Reads OntoWiki news from the AKSW RSS feed.
*
* @return array|Zend_Feed_Abstract
*/
public function getNews()
{
// get current version
$version = $this->_config->version;
// try reading
try {
if (isset($this->_config->news) && isset($this->_config->news->feedUrl)) {
$url = $this->_config->news->feedUrl;
} else {
$url = 'http://blog.aksw.org/feed/?cat=5&client='
. urlencode($version->label)
. '&version='
. urlencode($version->number)
. '&suffix='
. urlencode($version->suffix);
}
if ($url) {
$url = strtr(
$url, array(
'{{version.label}}' => urlencode($version->label),
'{{version.number}}' => urlencode($version->number),
'{{version.suffix}}' => urlencode($version->suffix)
)
);
/* @var $client Zend_Http_Client */
$client = Zend_Feed::getHttpClient();
$client->setConfig(array('timeout' => self::NEWS_FEED_TIMEOUT_IN_SECONDS));
$owFeed = Zend_Feed::import($url);
return $owFeed;
} else {
$message = 'Feed disabled in config.ini. You can configure a feed '
. 'using the "news.feedUrl" key in your config.ini.';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::INFO)
);
return array();
}
} catch (Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message('Error loading feed: ' . $url, OntoWiki_Message::WARNING)
);
return array();
}
}
}
================================================
FILE: application/controllers/ModelController.php
================================================
* @author Philipp Frischmuth
*/
class ModelController extends OntoWiki_Controller_Base
{
/**
* Adds statement to a named graph
*/
public function addAction()
{
$this->view->placeholder('main.window.title')->set('Import Statements to the Knowledge Base');
$this->_helper->viewRenderer->setScriptAction('create');
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->view->formActionUrl = $this->_config->urlBase . 'model/add';
$this->view->formEncoding = 'multipart/form-data';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formMethod = 'post';
$this->view->formName = 'addmodel';
$this->view->title = $this->view->_('Add Statements to Knowledge Base');
$model = $this->_owApp->selectedModel;
$this->view->modelTitle = $model->getTitle();
$this->view->importActions = $this->_getImportActions();
if ($model->isEditable()) {
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Add Data', 'id' => 'addmodel'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Cancel'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
} else {
$this->_owApp->appendMessage(
new OntoWiki_Message(
'No write permissions on model "' . $this->view->modelTitle . '"',
OntoWiki_Message::WARNING
)
);
return;
}
if (!$this->_request->isPost()) {
// FIX: http://www.webmasterworld.com/macintosh_webmaster/3300569.htm
// disable connection keep-alive
$response = $this->getResponse();
$response->setHeader('Connection', 'close', true);
$response->sendHeaders();
return;
} else {
$this->_doImportActionRedirect((string)$model);
}
}
/**
* Configures options for a specified graph.
*/
public function configAction()
{
$this->addModuleContext('main.window.modelconfig');
OntoWiki::getInstance()->getNavigation()->disableNavigation();
if (!$this->_request->getParam('m')) {
throw new OntoWiki_Controller_Exception("Missing parameter 'm'.");
}
$store = $this->_owApp->erfurt->getStore();
$graphUri = $this->_request->getParam('m');
$model = $store->getModel($graphUri);
// Make sure the current user is allowed to edit the model.
if (!$model || !$model->isEditable()) {
$this->_owApp->appendMessage(
new OntoWiki_Message("No write permissions on model '{$graphUri}'", OntoWiki_Message::WARNING)
);
return;
} else {
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Save Model Configuration'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Cancel'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
// get cache for invalidation later
$queryCache = $this->_erfurt->getQueryCache();
// disable versioning
$versioning = $this->_erfurt->getVersioning();
$versioning->enableVersioning(false);
// If there is POST data, this is the set request
if ($this->_request->isPost()) {
$this->view->clearModuleCache('modellist');
$post = $this->_request->getPost();
// Check the is hidden option.
if (isset($post['ishidden']) && $post['ishidden'] === 'ishidden') {
// In this case we need to set the value to true in the sys ont.
$model->setOption(
$this->_config->sysont->properties->hidden,
array(
array(
'value' => 'true',
'type' => 'literal',
'datatype' => EF_XSD_BOOLEAN
)
)
);
} else {
// We unset the value here (means not hidden).
$model->setOption($this->_config->sysont->properties->hidden);
}
// Check the is isLarge option.
if (isset($post['isLarge']) && $post['isLarge'] === 'isLarge') {
// In this case we need to set the value to true in the sys ont.
$model->setOption(
$this->_config->sysont->properties->isLarge,
array(
array(
'value' => 'true',
'type' => 'literal',
'datatype' => EF_XSD_BOOLEAN
)
)
);
} else {
// We unset the value here (means not hidden).
$model->setOption($this->_config->sysont->properties->isLarge);
}
// Check the use sysbase option.
if (isset($post['usesysbase']) && $post['usesysbase'] === 'usesysbase') {
// Checked, so check, whether the value is already set.
if ($graphUri !== $this->_config->sysbase->model) {
$useSysBaseOld = $model->getOption($this->_config->sysont->properties->hiddenImports);
if (null !== $useSysBaseOld) {
$alreadySet = false;
foreach ($useSysBaseOld as $row) {
if ($row['value'] === $this->_config->sysbase->model && $row['type'] === 'uri') {
$alreadySet = true;
break;
}
}
if (!$alreadySet) {
$useSysBaseNew = $useSysBaseOld;
$useSysBaseNew[] = array(
'type' => 'uri',
'value' => $this->_config->sysbase->model
);
$model->setOption($this->_config->sysont->properties->hiddenImports, $useSysBaseNew);
}
} else {
$useSysBaseNew = array();
$useSysBaseNew[] = array(
'type' => 'uri',
'value' => $this->_config->sysbase->model
);
$model->setOption($this->_config->sysont->properties->hiddenImports, $useSysBaseNew);
}
}
// Check whether SysBase is already available... If not import it.
if (!$store->isModelAvailable($this->_config->sysbase->model, false)) {
$m = $store->getNewModel($this->_config->sysbase->model, '', 'owl', false);
try {
if (is_readable($this->_config->sysbase->path)) {
// load SysOnt from file
$store->importRdf(
$this->_config->sysbase->model,
_OWROOT . $this->_config->sysbase->path,
'rdfxml',
Erfurt_Syntax_RdfParser::LOCATOR_FILE,
false
);
} else {
throw new Erfurt_Exception();
}
} catch (Erfurt_Exception $e) {
// Delete the model, for the import failed.
$store->deleteModel($this->_config->sysbase->model, false);
throw new Erfurt_Store_Exception(
'Import of "' . $this->_config->sysbase->model . '" failed: "' . $e->getMessage() . '"'
);
}
// Set SysBase hidden!
$m->setOption(
$this->_config->sysont->properties->hidden,
array(
array(
'value' => 'true',
'type' => 'literal',
'datatype' => EF_XSD_BOOLEAN
)
)
);
}
} else {
// Not checked... Remove if currently set.
if ($graphUri !== $this->_config->sysbase->model) {
$useSysBaseOld = $model->getOption($this->_config->sysont->properties->hiddenImports);
if (null !== $useSysBaseOld) {
$currentlySet = false;
foreach ($useSysBaseOld as $i => $row) {
if (($row['value'] === $this->_config->sysbase->model) && ($row['type'] === 'uri')) {
$currentlySet = true;
unset($useSysBaseOld[$i]);
break;
}
}
if ($currentlySet) {
$useSysBaseNew = $useSysBaseOld;
$model->setOption($this->_config->sysont->properties->hiddenImports, $useSysBaseNew);
}
}
}
}
/**
* insert a new prefix and namespace to the model
*/
if (isset($post['new_prefix_prefix']) || isset($post['new_prefix_namespace'])) {
if (!isset($post['new_prefix_prefix']) || !isset($post['new_prefix_namespace'])) {
// Incomplete input
$this->_owApp->appendMessage(
new OntoWiki_Message(
'Incomplete input, namespace or prefix is missing.',
OntoWiki_Message::ERROR
)
);
} else {
try {
if ($post['new_prefix_prefix'] != '' && $post['new_prefix_namespace'] != '') {
$model->addNamespacePrefix($post['new_prefix_prefix'], $post['new_prefix_namespace']);
}
} catch (Erfurt_Ac_Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message(
'No write permissions on model "' . $this->view->modelTitle . '"',
OntoWiki_Message::WARNING
)
);
} catch (Erfurt_Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message($e->getMessage(), OntoWiki_Message::ERROR)
);
}
}
}
// invalidate model and config model and sysbase if available
if ($store->isModelAvailable($this->_config->sysbase->model, false)) {
$queryCache->invalidateWithModelIri($this->_config->sysbase->model);
}
$queryCache->invalidateWithModelIri($this->_config->sysont->model);
$queryCache->invalidateWithModelIri($graphUri);
// Forward to info action
$this->_redirect(
$this->_config->urlBase . 'model/config/?m=' . urlencode($this->_request->m),
array('code' => 302)
);
return;
} else {
if (isset($this->_request->delete_prefix)) {
try {
$model->deleteNamespacePrefix($this->_request->delete_prefix);
} catch (Erfurt_Ac_Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message(
'No write permissions on model "' . $this->view->modelTitle . '"',
OntoWiki_Message::WARNING
)
);
} catch (Erfurt_Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message($e->getMessage(), OntoWiki_Message::ERROR)
);
}
// invalidate model and config model
$queryCache->invalidateWithModelIri($this->_config->sysont->model);
$queryCache->invalidateWithModelIri($graphUri);
// Forward to info action
$this->_redirect(
$this->_config->urlBase . 'model/config/?m=' . urlencode($this->_request->m),
array('code' => 302)
);
return;
} else {
// Set the window title in the appropriate language.
$translate = $this->_owApp->translate;
$windowTitle = $translate->_('Model Configuration');
$this->view->placeholder('main.window.title')->set($windowTitle);
$this->view->formActionUrl = $this->_config->urlBase . 'model/config';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'modelconfig';
$isLarge = $model->getOption($this->_config->sysont->properties->isLarge);
if (null !== $isLarge && ($isLarge[0]['value'] === 'true') || ($isLarge[0]['value'] == 1)) {
// Model does not count currently
$this->view->isLarge = 'checked="checked"';
} else {
$this->view->isLarge = '';
}
$isHidden = $model->getOption($this->_config->sysont->properties->hidden);
if (null !== $isHidden && ($isHidden[0]['value'] === 'true') || ($isHidden[0]['value'] == 1)) {
// Model is currently hidden
$this->view->isHidden = 'checked="checked"';
} else {
$this->view->isHidden = '';
}
$useSysBase = $model->getOption($this->_config->sysont->properties->hiddenImports);
$sysBaseImported = false;
if (is_array($useSysBase)) {
// Option is set... now check whether one of the values is the SysBase uri.
foreach ($useSysBase as $row) {
if ($row['value'] == $this->_config->sysbase->model) {
$sysBaseImported = true;
break;
}
}
}
if ($sysBaseImported) {
$this->view->useSysBase = 'checked="checked"';
} else {
$this->view->useSysBase = '';
// show a warning message
$translate = $this->_owApp->translate;
$messageText = 'This knowledge base does not import the OntoWiki System Base model.'
. ' This means you probably don\'t have human-readable representations for the'
. ' most commonly used vocabularies. If you want to use the OntoWiki System'
. ' Base just check the according box and click \'Save Model Configuration\'.';
$this->_owApp->appendMessage(
new OntoWiki_Message(
$translate->_($messageText),
OntoWiki_Message::WARNING
)
);
}
if ($graphUri === $this->_config->sysbase->model) {
$this->view->useSysBaseDisabled = 'disabled="disabled"';
} else {
$this->view->useSysBaseDisabled = '';
}
$this->view->readonly = 'readonly="readonly"';
$this->view->modeluri = $graphUri;
$this->view->baseuri = $model->getBaseUri();
/**
* Sending prefixes to the config view
*/
$prefixes = $model->getNamespacePrefixes();
$this->view->prefixes = array();
ksort($prefixes);
foreach ($prefixes as $prefix => $namespace) {
$this->view->prefixes[] = array($prefix, $namespace);
}
}
}
// re-enable versioning again
$versioning->enableVersioning(true);
}
/**
* Creates a new named graph
*/
public function createAction()
{
$this->addModuleContext('main.window.modelcreate');
$store = $this->_erfurt->getStore();
$this->view->clearModuleCache('modellist');
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->view->placeholder('main.window.title')->set('Create New Knowledge Base');
$this->view->formActionUrl = $this->_config->urlBase . 'model/create';
$this->view->formEncoding = 'multipart/form-data';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formMethod = 'post';
$this->view->formName = 'createmodel';
// this is the default action
$defaultActions = array(
'empty' => array(
'parameter' => 'checked',
'controller' => 'model',
'action' => 'info',
'label' => 'Create a (nearly) empty knowledge base',
'description' => 'Just add the label and type to the new model.'
)
);
$importActions = array_merge($defaultActions, $this->_getImportActions());
$this->view->importActions = $importActions;
if (!$this->_erfurt->isActionAllowed('ModelManagement')) {
$this->_owApp->appendMessage(
new OntoWiki_Message('Model management is not allowed.', OntoWiki_Message::ERROR)
);
$this->view->errorFlag = true;
return;
}
// TODO: add this to the template in order to allow users to tune it
$this->view->modelUri = $this->_config->urlBase .'NEWMODEL/';
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(
OntoWiki_Toolbar::SUBMIT,
array('name' => 'Create Knowledge Base', 'id' => 'createmodel')
)->appendButton(
OntoWiki_Toolbar::RESET,
array('name' => 'Cancel', 'id' => 'createmodel')
);
$this->view->placeholder('main.window.toolbar')->set($toolbar);
$this->view->title = $this->view->_('Create Knowledge Base');
if (!$this->_request->isPost()) {
// FIX: http://www.webmasterworld.com/macintosh_webmaster/3300569.htm
// disable connection keep-alive
$response = $this->getResponse();
$response->setHeader('Connection', 'close', true);
$response->sendHeaders();
return;
} else {
// process the user input
$post = $this->_request->getPost();
// determine or create the model URI
$newModelUri = '';
if (trim($post['modeluri']) != '') {
// URI given via form input
$newModelUri = trim($post['modeluri']);
} else if (trim($post['title']) != '') {
// create a nice URI from the title (poor mans way)
$urlBase = $this->_config->urlBase;
$title = trim($post['title']);
$title = str_replace(' ', '', $title);
$title = urlencode($title);
$newModelUri = $urlBase . $title . '/';
} else {
// create a default model with counter
$urlBase = $this->_config->urlBase . 'kb';
$counter = 0;
do {
$newModelUri = $urlBase . ($counter++) . '/';
} while ($store->isModelAvailable($newModelUri, false));
}
if ($newModelUri == '') {
$this->_owApp->appendMessage(
new OntoWiki_Message(
'Please provide at least a valid URI for the new Knowledge Base.',
OntoWiki_Message::ERROR
)
);
$this->view->errorFlag = true;
return;
}
// create model
if ($store->isModelAvailable($newModelUri, false)) {
// model exists
$this->_owApp->appendMessage(
new OntoWiki_Message('Given Knowledge Base already exists.', OntoWiki_Message::ERROR)
);
$this->view->errorFlag = true;
return;
} else if (filter_var($newModelUri, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED) === false
&& strcmp(substr($newModelUri, 0, 4), 'urn:') != 0
) {
//the filter doesnt filter urn's properly, hence they are excluded from the check
$this->_owApp->appendMessage(
new OntoWiki_Message('The given String is no legal URI', OntoWiki_Message::ERROR)
);
} else {
// model does not exist, will be created
$model = $store->getNewModel(
$newModelUri, $newModelUri, Erfurt_Store::MODEL_TYPE_OWL
);
$this->_owApp->appendMessage(
new OntoWiki_Message('Knowledge Base successfully created.', OntoWiki_Message::SUCCESS)
);
// add label
$additions = new Erfurt_Rdf_MemoryModel();
if (isset($post['title']) && trim($post['title']) != '') {
$additions->addAttribute($newModelUri, EF_RDFS_LABEL, $post['title']);
}
$model->addMultipleStatements($additions->getStatements());
// TODO: add ACL infos based on the post data
$this->_doImportActionRedirect($newModelUri);
}
}
}
public function deleteAction()
{
$model = $this->_request->model;
if ($this->_erfurt->isActionAllowed('ModelManagement')) {
$event = new Erfurt_Event('onPreDeleteModel');
$event->modelUri = $model;
$event->trigger();
try {
$this->_erfurt->getStore()->deleteModel($model);
if ((null !== $this->_owApp->selectedModel)
&& ($this->_owApp->selectedModel->getModelIri() === $model)
) {
$this->_owApp->selectedModel = null;
//deletes selected model - always needed?
$this->view->clearModuleCache();
$url = new OntoWiki_Url(
array(
'controller' => $this->_config->index->default->controller,
'action' => $this->_config->index->default->action,
),
array()
);
$this->_redirect($url, array('code' => 302));
}
} catch (Exception $e) {
$this->_owApp->appendMessage(
new OntoWiki_Message(
'Error deleting model: ' . $e->getMessage() . ' ' . $e->getTraceAsString(),
OntoWiki_Message::ERROR
)
);
}
} else {
$this->_owApp->appendMessage(
new OntoWiki_Message('Error deleting model: Not allowed.', OntoWiki_Message::ERROR)
);
$this->_redirect($_SERVER['HTTP_REFERER'], array('code' => 302));
return;
}
$this->view->clearModuleCache(); //deletes selected model - always needed?
$this->_redirect($_SERVER['HTTP_REFERER'], array('code' => 302));
}
/**
* Serializes a given model or (if supported) all models into a given format.
*/
public function exportAction()
{
if (!$this->_owApp->erfurt->getAc()->isActionAllowed(Erfurt_Ac_Default::ACTION_MODEL_EXPORT)) {
$this->_owApp->appendMessage(
new OntoWiki_Message('Model export not allowed.', OntoWiki_Message::ERROR)
);
$this->_redirect($_SERVER['HTTP_REFERER'], array('code' => 302));
return;
}
// Check whether the f parameter is given. If not: default to rdf/xml
if (!isset($this->_request->f)) {
$format = 'rdfxml';
} else {
$format = $this->_request->f;
}
$format = Erfurt_Syntax_RdfSerializer::normalizeFormat($format);
$store = $this->_erfurt->getStore();
// Check whether given format is supported. If not: 400 Bad Request.
if (!in_array($format, array_keys(Erfurt_Syntax_RdfSerializer::getSupportedFormats()))) {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 400 Bad Request');
throw new OntoWiki_Controller_Exception("Format '$format' not supported.");
}
// Check whether a model uri is given
if (isset($this->_request->m)) {
$modelUri = $this->_request->m;
// Check whether model exists. If not: 404 Not Found.
if (!$store->isModelAvailable($modelUri, false)) {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 404 Not Found');
throw new OntoWiki_Controller_Exception("Model '$modelUri' not found.");
}
// Check whether model is available (with acl). If not: 403 Forbidden.
if (!$store->isModelAvailable($modelUri)) {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 403 Forbidden');
throw new OntoWiki_Controller_Exception("Model '$modelUri' not available.");
}
$filename = 'export' . date('Y-m-d_Hi');
$description = Erfurt_Syntax_RdfSerializer::getFormatDescription($format);
$contentType = $description['contentType'];
$filename .= $description['fileExtension'];
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$response = $this->getResponse();
$response->setHeader('Content-Type', $contentType, true);
$response->setHeader('Content-Disposition', ('filename="' . $filename . '"'));
$serializer = Erfurt_Syntax_RdfSerializer::rdfSerializerWithFormat($format);
echo $serializer->serializeGraphToString($modelUri);
return;
} else {
// Else use all available models.
// TODO Exporters need to support this feature...
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 400 Bad Request');
throw new OntoWiki_Controller_Exception("No Graph URI given.");
}
}
public function infoAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->_owApp->selectedResource = new OntoWiki_Resource(
$this->_request->getParam('m'), $this->_owApp->selectedModel
);
$store = $this->_owApp->erfurt->getStore();
$graph = $this->_owApp->selectedModel;
$resource = $this->_owApp->selectedResource;
$translate = $this->_owApp->translate;
$event = new Erfurt_Event('onPropertiesAction');
$event->uri = (string)$resource;
$event->graph = (string)$resource;
$event->trigger();
$windowTitle = $translate->_('Model info');
$this->view->placeholder('main.window.title')->set($windowTitle);
$title = $resource->getTitle($this->_owApp->getConfig()->languages->locale);
$this->view->modelTitle = $title ? $title : OntoWiki_Utils::contractNamespace((string)$resource);
$resourcesUrl = new OntoWiki_Url(array('route' => 'instances'), array());
$resourcesUrl->init = true;
$this->view->resourcesUrl = (string)$resourcesUrl;
if (!empty($resource)) {
$model = new OntoWiki_Model_Resource($store, $graph, (string)$resource);
$values = $model->getValues();
$predicates = $model->getPredicates();
$titleHelper = new OntoWiki_Model_TitleHelper($graph);
$graphs = array_keys($predicates);
$titleHelper->addResources($graphs);
$graphInfo = array();
$editableFlags = array();
foreach ($graphs as $g) {
$graphInfo[$g] = $titleHelper->getTitle($g, $this->_config->languages->locale);
$editableFlags[$g] = false;
}
$this->view->graphs = $graphInfo;
$this->view->resourceIri = (string)$resource;
$this->view->graphIri = $graph->getModelIri();
$this->view->values = $values;
$this->view->predicates = $predicates;
$this->view->graphBaseIri = $graph->getBaseIri();
$this->view->namespacePrefixes = $graph->getNamespacePrefixes();
$this->view->editableFlags = $editableFlags;
if (!is_array($this->view->namespacePrefixes)) {
$this->view->namespacePrefixes = array();
}
if (!array_key_exists(OntoWiki_Utils::DEFAULT_BASE, $this->view->namespacePrefixes)) {
$this->view->namespacePrefixes[OntoWiki_Utils::DEFAULT_BASE] = $graph->getBaseIri();
}
$infoUris = $this->_config->descriptionHelper->properties;
if (count($values) > 0) {
$query = 'ASK FROM <' . (string)$resource . '>'
. ' WHERE {'
. ' <' . (string)$resource . '> a '
. ' }';
$q = Erfurt_Sparql_SimpleQuery::initWithString($query);
if ($this->_owApp->extensionManager->isExtensionActive('foafprofileviewer')
&& $store->sparqlAsk($q) === true
) {
$this->view->showFoafLink = true;
$this->view->foafLink = $this->_config->urlBase . 'foafprofileviewer/display';
}
}
$this->view->infoPredicates = array();
foreach ($infoUris as $infoUri) {
if (isset($predicates[(string)$graph]) && array_key_exists($infoUri, $predicates[(string)$graph])) {
$this->view->infoPredicates[$infoUri] = $predicates[(string)$graph][$infoUri];
}
}
}
$this->addModuleContext('main.window.modelinfo');
}
public function selectAction()
{
if (isset($this->_request->m)) {
// reset resource/class
unset($this->_owApp->selectedResource);
unset($this->_owApp->selectedClass);
unset($this->_session->hierarchyOpen);
$this->_redirect(
$this->_config->urlBase . 'model/info/?m=' . urlencode($this->_request->m),
array('code' => 302)
);
}
$this->_redirect($this->_config->urlBase, array('code' => 302));
}
/**
* Updates the current model with statements sent as JSON
*/
public function updateAction()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout()->disableLayout();
$errors = array();
// check graph parameter
if (!$this->_request->has('named-graph-uri')) {
$errors[] = "Missing parameter 'named-graph-uri'.";
}
// Parsing may go wrong, when user types in corrupt data... So we catch all exceptions here...
try {
$flag = false;
// check original graph
if ($this->_request->has('original-graph')) {
$flag = true;
$originalFormat = $this->_request->getParam('original-format', 'rdfjson');
$parser = Erfurt_Syntax_RdfParser::rdfParserWithFormat($originalFormat);
$originalStatements = $parser->parse(
$this->getParam('original-graph', false),
Erfurt_Syntax_RdfParser::LOCATOR_DATASTRING
);
}
// check changed graph
if ($this->_request->has('modified-graph')) {
$flag = true;
$modifiedFormat = $this->_request->getParam('modified-format', 'rdfjson');
$parser = Erfurt_Syntax_RdfParser::rdfParserWithFormat($modifiedFormat);
$modifiedStatements = $parser->parse(
$this->getParam('modified-graph', false),
Erfurt_Syntax_RdfParser::LOCATOR_DATASTRING
);
}
} catch (Exception $e) {
$errors[] = 'Something went wrong: ' . $e->getMessage();
}
if (!$flag) {
$errors[] = "At least one of the parameters 'original-graph' or 'modified-graph' must be supplied.";
}
// errors occured... so do not update... instead show error message or mark as bad request
if (!empty($errors)) {
if (null === $this->_request->getParam('redirect-uri')) {
// This means, we do not redirect, so we can mark this request as bad request.
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 400 Bad Request');
throw new OntoWiki_Controller_Exception(implode(PHP_EOL, $errors));
} else {
// We have a redirect uri given, so we do not redirect, but show the error messages
foreach ($errors as $e) {
$this->_owApp->appendMessage(new OntoWiki_Message($e, OntoWiki_Message::ERROR));
}
$server = $this->_request->getServer();
if (isset($server['HTTP_REFERER'])) {
$this->_request->setParam('redirect-uri', $server['HTTP_REFERER']);
}
return;
}
}
// instantiate model
$graph = Erfurt_App::getInstance()->getStore()->getModel($this->getParam('named-graph-uri'));
// update model
$graph->updateWithMutualDifference($originalStatements, $modifiedStatements);
}
/**
* prepare and do the redirect
*/
private function _doImportActionRedirect($modelUri)
{
$id = $this->_request->getPost('importAction');
$importOptions = $this->_request->getPost('importOptions');
$actions = $this->_getImportActions();
if (isset($actions[$id])) {
$controller = $actions[$id]['controller'];
$action = $actions[$id]['action'];
} else {
$controller = 'model';
$action = 'info';
}
$url = new OntoWiki_Url(
array(
'controller' => $controller,
'action' => $action
),
array('m', 'importOptions')
);
$url->setParam('m', $modelUri);
$url->setParam('importOptions', $importOptions);
$this->_redirect($url, array('code' => 302));
}
private function _getImportActions()
{
/**
* @trigger onProvideImportActions event to provide additional import actions
*
* Parameter: importActions
*
* Example:
*
* array(
* 'controller' => 'model',
* 'action' => 'info',
* 'label' => 'Create an (nearly) empty knowledge base',
* 'description' => 'Just add the label to the new model.'
* ));
* ?>
*
*/
$event = new Erfurt_Event('onProvideImportActions');
$event->importActions = array();
$result = $event->trigger();
return $event->importActions;
}
}
================================================
FILE: application/controllers/ModuleController.php
================================================
*/
class ModuleController extends OntoWiki_Controller_Base
{
public function indexAction()
{
$this->_forward('get');
}
public function getAction()
{
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
// mandatory
if (!isset($this->_request->name)) {
throw new OntoWiki_Exeption("Missing parameter 'name'.");
}
$name = $this->_request->name;
if (isset($this->_request->class)) {
$class = $this->_request->class;
} else {
$class = '';
}
if (isset($this->_request->id)) {
$id = $this->_request->id;
} else {
$id = '';
}
$this->_response->setHeader('Content-Type', 'text/html');
$this->_response->setBody(
$this->view->module($name, new Zend_Config(array('classes' => $class, 'id' => $id), true))
);
}
}
================================================
FILE: application/controllers/ResourceController.php
================================================
_owApp->selectedResource;
$m = $this->_owApp->selectedModel;
if (!$m || !$r) {
return;
}
$versioning = Erfurt_App::getInstance()->getVersioning();
$lastModArray = $versioning->getLastModifiedForResource($r, $m->getModelUri());
if (null === $lastModArray || !is_numeric($lastModArray['tstamp'])) {
return;
}
$response = $this->getResponse();
$response->setHeader('Last-Modified', date('r', $lastModArray['tstamp']), true);
}
/**
* Displays all preoperties and values for a resource, denoted by parameter
*/
public function propertiesAction()
{
$this->_addLastModifiedHeader();
$store = $this->_owApp->erfurt->getStore();
$graph = $this->_owApp->selectedModel;
$resource = $this->_owApp->selectedResource;
$navigation = $this->_owApp->navigation;
$translate = $this->_owApp->translate;
// add export formats to resource menu
$resourceMenu = OntoWiki_Menu_Registry::getInstance()->getMenu('resource');
$menu = new OntoWiki_Menu();
$menu->setEntry('Resource', $resourceMenu);
$event = new Erfurt_Event('onCreateMenu');
$event->menu = $resourceMenu;
$event->resource = $this->_owApp->selectedResource;
$event->model = $this->_owApp->selectedModel;
$event->trigger();
$event = new Erfurt_Event('onPropertiesAction');
$event->uri = (string)$resource;
$event->graph = $this->_owApp->selectedModel->getModelUri();
$event->trigger();
// Give plugins a chance to add entries to the menu
$this->view->placeholder('main.window.menu')->set($menu->toArray(false, true));
if ($resource->getTitle($this->_config->languages->locale)) {
$title = $resource->getTitle($this->_config->languages->locale);
} else {
$title = OntoWiki_Utils::contractNamespace((string)$resource);
}
$windowTitle = sprintf($translate->_('Properties of %1$s'), $title);
$this->view->placeholder('main.window.title')->set($windowTitle);
if (!empty($resource)) {
$event = new Erfurt_Event('onPreTabsContentAction');
$event->uri = (string)$resource;
$result = $event->trigger();
if ($result) {
$this->view->preTabsContent = $result;
}
$event = new Erfurt_Event('onPrePropertiesContentAction');
$event->uri = (string)$resource;
$result = $event->trigger();
if ($result) {
$this->view->prePropertiesContent = $result;
}
$model = new OntoWiki_Model_Resource($store, $graph, (string)$resource);
$values = $model->getValues();
$predicates = $model->getPredicates();
// new trigger onPropertiesActionData to work with data (reorder with plugin)
$event = new Erfurt_Event('onPropertiesActionData');
$event->uri = (string)$resource;
$event->predicates = $predicates;
$event->values = $values;
$result = $event->trigger();
if ($result) {
$predicates = $event->predicates;
$values = $event->values;
}
$titleHelper = new OntoWiki_Model_TitleHelper($graph);
// add graphs
$graphs = array_keys($predicates);
$titleHelper->addResources($graphs);
// set RDFa widgets update info for editable graphs and other graph info
$graphInfo = array();
$editableFlags = array();
foreach ($graphs as $g) {
$graphInfo[$g] = $titleHelper->getTitle($g, $this->_config->languages->locale);
if ($this->_erfurt->getAc()->isModelAllowed('edit', $g)) {
$editableFlags[$g] = true;
$this->view->placeholder('update')->append(
array(
'sourceGraph' => $g,
'queryEndpoint' => $this->_config->urlBase . 'sparql/',
'updateEndpoint' => $this->_config->urlBase . 'update/'
)
);
} else {
$editableFlags[$g] = false;
}
}
$this->view->graphs = $graphInfo;
$this->view->editableFlags = $editableFlags;
$this->view->values = $values;
$this->view->predicates = $predicates;
$this->view->resourceUri = (string)$resource;
$this->view->graphUri = $graph->getModelIri();
$this->view->graphBaseUri = $graph->getBaseIri();
$this->view->editable = false; // use $this->editableFlags[$graph] now
// prepare namespaces
$namespacePrefixes = $graph->getNamespacePrefixes();
$graphBase = $graph->getBaseUri();
if (!array_key_exists(OntoWiki_Utils::DEFAULT_BASE, $namespacePrefixes)) {
$namespacePrefixes[OntoWiki_Utils::DEFAULT_BASE] = $graphBase;
}
$this->view->namespacePrefixes = $namespacePrefixes;
}
$toolbar = $this->_owApp->toolbar;
// show only if not forwarded and if model is writeable
// TODO: why is isEditable not false here?
if ($this->_request->getParam('action') == 'properties' && $graph->isEditable()
&& $this->_owApp->erfurt->getAc()->isModelAllowed('edit', $this->_owApp->selectedModel)
) {
// TODO: check acl
$toolbar->appendButton(
OntoWiki_Toolbar::EDIT,
array('name' => 'Edit Properties', 'title' => 'SHIFT + ALT + e')
);
$toolbar->appendButton(
OntoWiki_Toolbar::EDITADD,
array(
'name' => 'Clone',
'class' => 'clone-resource',
'title' => 'SHIFT + ALT + l'
)
);
$url = new OntoWiki_Url(
array('controller' => 'resource', 'action' => 'delete'),
array('r')
);
$url->setParam('r', (string)$resource, false);
$params = array(
'name' => 'Delete',
'url' => (string)$url
);
$toolbar->appendButton(OntoWiki_Toolbar::SEPARATOR);
$toolbar->appendButton(OntoWiki_Toolbar::DELETE, $params);
$toolbar->prependButton(OntoWiki_Toolbar::SEPARATOR);
$toolbar->prependButton(
OntoWiki_Toolbar::ADD,
array(
'name' => 'Add Property',
'+class' => 'property-add',
'title' => 'SHIFT + ALT + a'
)
);
$toolbar->prependButton(OntoWiki_Toolbar::SEPARATOR);
$toolbar->prependButton(
OntoWiki_Toolbar::CANCEL,
array(
'+class' => 'hidden',
'title' => 'SHIFT + ALT + c'
)
);
$toolbar->prependButton(
OntoWiki_Toolbar::SAVE,
array(
'+class' => 'hidden',
'title' => 'SHIFT + ALT + s'
)
);
}
// let plug-ins add buttons
$toolbarEvent = new Erfurt_Event('onCreateToolbar');
$toolbarEvent->resource = (string)$resource;
$toolbarEvent->graph = (string)$graph;
$toolbarEvent->toolbar = $toolbar;
$eventResult = $toolbarEvent->trigger();
if ($eventResult instanceof OntoWiki_Toolbar) {
$toolbar = $eventResult;
}
// add toolbar
$this->view->placeholder('main.window.toolbar')->set($toolbar);
//show modules
$this->addModuleContext('main.window.properties');
}
/**
* Displays resources of a certain type and property values that have
* been selected by the user.
*/
public function instancesAction()
{
$store = $this->_owApp->erfurt->getStore();
$graph = $this->_owApp->selectedModel;
// the list is managed by a controller plugin that catches special http-parameters
// @see Ontowiki/Controller/Plugin/ListSetupHelper.php
//here this list is added to the view
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
$listName = 'instances';
if ($listHelper->listExists($listName)) {
$list = $listHelper->getList($listName);
$list->setStore($store);
$listHelper->addList($listName, $list, $this->view);
} else {
if ($this->_owApp->selectedModel == null) {
$this->_owApp->appendMessage(
new OntoWiki_Message('your session timed out. select a model', OntoWiki_Message::ERROR)
);
$this->_redirect($this->_config->baseUrl);
}
$list = new OntoWiki_Model_Instances($store, $this->_owApp->selectedModel, array());
$listHelper->addListPermanently($listName, $list, $this->view);
}
//begin view building
$this->view->placeholder('main.window.title')->set('Resource List');
// rdfauthor on a list is not possible yet
// TODO: check acl
// build toolbar
/*
* toolbar disabled for 0.9.5 (reactived hopefully later :) ) */
if ($graph->isEditable()) {
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(
OntoWiki_Toolbar::EDITADD, array('name' => 'Add Instance', 'class' => 'init-resource')
);
$toolbar->prependButton(OntoWiki_Toolbar::SEPARATOR);
$toolbar->prependButton(
OntoWiki_Toolbar::CANCEL,
array(
'+class' => 'hidden',
'title' => 'SHIFT + ALT + c'
)
);
$toolbar->prependButton(
OntoWiki_Toolbar::SAVE,
array(
'+class' => 'hidden',
'title' => 'SHIFT + ALT + s'
)
);
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
$url = new OntoWiki_Url();
$this->view->redirectUrl = (string)$url;
$this->addModuleContext('main.window.list');
$this->addModuleContext('main.window.instances');
}
/**
* Deletes one or more resources denoted by param 'r'
* TODO: This should be done by a evolution pattern in the future
*/
public function deleteAction()
{
$this->view->clearModuleCache();
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
$store = $this->_erfurt->getStore();
$model = $this->_owApp->selectedModel;
$modelIri = (string)$model;
$redirect = $this->_request->getParam('redirect', $this->_config->urlBase);
if (isset($this->_request->r)) {
$resources = $this->_request->getParam('r', array());
} else {
throw new OntoWiki_Exception('Missing parameter r!');
}
if (!is_array($resources)) {
$resources = array($resources);
}
// get versioning
$versioning = $this->_erfurt->getVersioning();
$count = 0;
if ($this->_erfurt->getAc()->isModelAllowed('edit', $modelIri)) {
foreach ($resources as $resource) {
// if we have only a nice uri, fill to full uri
if (Zend_Uri::check($resource) == false) {
// check for namespace
if (strstr($resource, ':')) {
$resource = OntoWiki_Utils::expandNamespace($resource);
} else {
$resource = $model->getBaseIri() . $resource;
}
}
// action spec for versioning
$actionSpec = array();
$actionSpec['type'] = 130;
$actionSpec['modeluri'] = $modelIri;
$actionSpec['resourceuri'] = $resource;
// starting action
$versioning->startAction($actionSpec);
$stmtArray = array();
// query for all triples to delete them
$sparqlQuery = new Erfurt_Sparql_SimpleQuery();
$sparqlQuery->setSelectClause('SELECT ?p ?o');
$sparqlQuery->addFrom($modelIri);
$sparqlQuery->setWherePart('{ <' . $resource . '> ?p ?o . }');
$result = $store->sparqlQuery($sparqlQuery, array('result_format' => 'extended'));
// transform them to statement array to be compatible with store methods
foreach ($result['results']['bindings'] as $stmt) {
$stmtArray[$resource][$stmt['p']['value']][] = $stmt['o'];
}
$store->deleteMultipleStatements($modelIri, $stmtArray);
// stopping action
$versioning->endAction();
$count++;
}
$message = $count
. ' resource' . ($count != 1 ? 's' : '')
. ($count ? ' successfully' : '')
. ' deleted.';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::SUCCESS)
);
} else {
$message = 'not allowed.';
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::WARNING)
);
}
$event = new Erfurt_Event('onDeleteResources');
$event->resourceArray = $resources;
$event->modelUri = $modelIri;
$event->trigger();
$this->_redirect($redirect, array('code' => 302));
}
public function exportAction()
{
$this->_addLastModifiedHeader();
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
if (isset($this->_request->m)) {
$modelUri = $this->_request->m;
} else {
if (isset($this->_owApp->selectedModel)) {
$modelUri = $this->_owApp->selectedModel->getModelUri();
} else {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 400 Bad Request');
throw new OntoWiki_Controller_Exception("No model given.");
}
}
$resource = $this->getParam('r', true);
// Check whether the f parameter is given. If not: default to rdf/xml
if (!isset($this->_request->f)) {
$format = 'rdfxml';
} else {
$format = $this->_request->f;
}
$format = Erfurt_Syntax_RdfSerializer::normalizeFormat($format);
$store = $this->_erfurt->getStore();
// Check whether given format is supported. If not: 400 Bad Request.
if (!in_array($format, array_keys(Erfurt_Syntax_RdfSerializer::getSupportedFormats()))) {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 400 Bad Request');
throw new OntoWiki_Controller_Exception("Format '$format' not supported.");
}
// Check whether model exists. If not: 404 Not Found.
if (!$store->isModelAvailable($modelUri, false)) {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 404 Not Found');
throw new OntoWiki_Controller_Exception("Model '$modelUri' not found.");
}
// Check whether model is available (with acl). If not: 403 Forbidden.
if (!$store->isModelAvailable($modelUri)) {
$response = $this->getResponse();
$response->setRawHeader('HTTP/1.0 403 Forbidden');
throw new OntoWiki_Controller_Exception("Model '$modelUri' not available.");
}
$filename = 'export' . date('Y-m-d_Hi');
$formatDescription = Erfurt_Syntax_RdfSerializer::getFormatDescription($format);
$contentType = $formatDescription['contentType'];
$filename .= $formatDescription['fileExtension'];
/*
* Event: allow for adding / deleting statements to the export
* event uses a memory model and gets an empty memory model as
* default value, all plugins should add statements to the existing
* value and should not create a new model as return value
*/
$event = new Erfurt_Event('beforeExportResource');
$event->resource = $resource;
$event->modelUri = $modelUri;
$event->setDefault = new Erfurt_Rdf_MemoryModel();
$addedModel = $event->trigger();
if (is_object($addedModel) && get_class($addedModel) == 'Erfurt_Rdf_MemoryModel') {
$addedStatements = $addedModel->getStatements();
} else {
$addedStatements = array();
}
$response = $this->getResponse();
$response->setHeader('Content-Type', $contentType, true);
$response->setHeader('Content-Disposition', ('filename="' . $filename . '"'));
$serializer = Erfurt_Syntax_RdfSerializer::rdfSerializerWithFormat($format);
echo $serializer->serializeResourceToString($resource, $modelUri, false, true, $addedStatements);
}
public function headAction()
{
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
// disable rendering
$this->_helper->viewRenderer->setNoRender();
$redirect = $this->getParam('noredirect', false);
$resourceUri = $this->getParam('r', '');
if ("" == $resourceUri) {
echo json_encode(array());
} else {
$options = array(
'timeout' => 30
);
if ('true' == $redirect) {
$options['maxredirects'] = 0;
}
$httpClient = Erfurt_App::getInstance()->getHttpClient($resourceUri, $options);
$httpClient->setHeaders(
'Accept',
'text/turtle; q=1.0, application/x-turtle; q=0.9, text/n3; ' .
'q=0.8, application/rdf+xml; q=0.5, text/plain; q=0.1'
);
echo json_encode($httpClient->request()->getHeaders());
}
}
}
================================================
FILE: application/controllers/ServiceController.php
================================================
_config->service->allowGetAuth) {
// disallow get
if (!$this->_request->isPost()) {
$this->_response->setHttpResponseCode(405);
$this->_response->setHeader('Allow', 'POST');
return;
}
}
// fetch params
$l = $this->_request->logout;
if (isset($l) && ('true' == $l || 'false' == $l)) {
$logout = $this->_request->logout == 'true' ? true : false;
} elseif (isset($this->_request->u)) {
$username = $this->_request->u;
$password = $this->_request->getParam('p', '');
} else {
$this->_response->setHttpResponseCode(400);
return;
}
if (isset($logout) && true == $logout) {
// logout
Erfurt_Auth::getInstance()->clearIdentity();
session_destroy();
$this->_response->setHttpResponseCode(200);
return;
} else {
// authenticate
$result = $this->_owApp->erfurt->authenticate($username, $password);
}
// return HTTP result
if ($result->isValid()) {
$this->_response->setHttpResponseCode(200);
return;
} else {
$this->_response->setHttpResponseCode(401);
return;
}
}
public function hierarchyAction()
{
$options = array();
if (isset($this->_request->entry)) {
$options['entry'] = $this->_request->entry;
}
$model = new OntoWiki_Model_Hierarchy(
Erfurt_App::getInstance()->getStore(),
$this->_owApp->selectedModel,
$options
);
$this->view->open = true;
$this->view->classes = $model->getHierarchy();
$this->_response->setBody($this->view->render('partials/hierarchy_list.phtml'));
}
/**
* Constructor
*/
public function init()
{
// init controller variables
$this->_owApp = OntoWiki::getInstance();
$this->_config = $this->_owApp->config;
$this->_session = $this->_owApp->session;
// prepare Ajax context
$ajaxContext = $this->_helper->getHelper('AjaxContext');
$ajaxContext->addActionContext('view', 'html')
->addActionContext('form', 'html')
->addActionContext('process', 'json')
->initContext();
}
/**
* Menu Action to generate JSON serializations of OntoWiki_Menu for context-, module-, component-menus
*/
public function menuAction()
{
$module = $this->_request->getParam('module');
$resource = $this->_request->getParam('resource');
$model = $this->_request->getParam('model');
$translate = $this->_owApp->translate;
// create empty menu first
$menuRegistry = OntoWiki_Menu_Registry::getInstance();
if (!empty($resource)) {
$menu = $menuRegistry->getMenu('resource', $resource);
} else if (!empty($model)) {
$menu = $menuRegistry->getMenu('model', $model);
}
if (!empty($module)) {
$moduleRegistry = OntoWiki_Module_Registry::getInstance();
$menu = $moduleRegistry->getModule($module)->getContextMenu();
}
// Fire a event;
$event = new Erfurt_Event('onCreateMenu');
$event->menu = $menu;
$event->resource = $resource;
if (!empty($model)) {
$event->isModel = true;
$event->model = $model;
} else {
$event->model = $this->_owApp->selectedModel;
}
$event->trigger();
echo $menu->toJson();
}
public function preDispatch()
{
// disable auto-rendering
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
}
public function sessionAction()
{
if (!isset($this->_request->name)) {
throw new OntoWiki_Exception("Missing parameter 'name'.");
}
if (isset($this->_request->namespace)) {
$namespace = $this->_request->namespace;
} else {
$namespace = _OWSESSION;
}
$session = new Zend_Session_Namespace($namespace);
$name = $this->_request->name;
$method = 'set'; // default
if (isset($this->_request->method)) {
$method = $this->_request->method;
}
if (isset($this->_request->value)) {
$value = $this->_request->value;
} else {
if (($method != 'unsetArray')
&& ($method != 'unsetArrayKey')
&& !($method == 'unset' && !is_array($session->$name))
) {
throw new OntoWiki_Exception('Missing parameter "value".');
}
}
if (isset($this->_request->value) && isset($this->_request->valueIsSerialized)
&& $this->_request->valueIsSerialized == "true"
) {
$value = json_decode(stripslashes($value), true);
}
if (isset($this->_request->key)) {
$key = $this->_request->key;
} else {
if ($method == 'setArrayValue' || $method == 'unsetArrayKey') {
throw new OntoWiki_Exception('Missing parameter "key".');
}
}
switch ($method) {
case 'set':
$session->$name = $value;
break;
case 'setArrayValue':
if (!is_array($session->$name)) {
$session->$name = array();
}
$array = $session->$name;
$array[$key] = $value;
$session->$name = $array; //strange (because the __get and __set interceptors)
break;
case 'push':
if (!is_array($session->$name)) {
$session->$name = array();
}
array_push($session->$name, $value);
break;
case 'merge':
if (!is_array($session->$name)) {
$session->$name = array();
}
$session->$name = array_merge($session->$name, $value);
break;
case 'unset':
// unset a value by inverting the array
// and unsetting the specified key
if (is_array($session->$name)) {
$valuesAsKeys = array_flip($session->$name);
unset($valuesAsKeys[$value]);
$session->$name = array_flip($valuesAsKeys);
} else {
//unset a non-array
unset($session->$name);
}
break;
case 'unsetArrayKey':
//done this way because of interceptor-methods...
$new = array();
if (is_array($session->$name)) {
foreach ($session->$name as $comparekey => $comparevalue) {
if ($comparekey != $key) {
$new[] = $comparevalue;
}
}
}
$session->$name = $new;
break;
case 'unsetArray':
// unset the array
// (the above unsets only values in arrays)
unset($session->$name);
break;
}
$msg = 'sessionStore: '
. $name
. ' = '
. print_r($session->$name, true);
$this->_owApp->logger->debug($msg);
}
/**
* This action returns status values of the current session, like the selectedModel and the
* logged in User as JSON object.
*/
public function statusAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$status = new stdClass();
if (isset($this->_owApp->selectedModel)) {
$status->selectedModel = $this->_owApp->selectedModel->getModelIri();
} else {
$status->selectedModel = null;
}
$user = $this->_owApp->getUser();
if (get_class($user) == 'Erfurt_Auth_Identity') {
// TODO add serialization method to Erfurt_Auth_Identity
$status->user = new stdClass();
$status->user->isAnonymous = $user->isAnonymousUser();
$status->user->uri = $user->getUri();
$status->user->username = $user->getUsername();
} else {
$status->user = null;
}
$status->hasMessages = $this->_owApp->hasMessages();
// TODO add method to get sessionVars to OntoWiki class and dump them all into this status
$response = $this->getResponse();
$response->setHeader('Content-Type', 'application/json');
$response->setBody(json_encode($status));
}
/**
* OntoWiki Sparql Endpoint
*
* Implements the SPARQL protocol according to {@link http://www.w3.org/TR/rdf-sparql-protocol/}.
*/
public function sparqlAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$store = OntoWiki::getInstance()->erfurt->getStore();
$response = $this->getResponse();
// fetch params
// TODO: support maxOccurs:unbound
$queryString = $this->_request->getParam('query', '');
if (get_magic_quotes_gpc()) {
$queryString = stripslashes($queryString);
}
$defaultGraph = $this->_request->getParam('default-graph-uri', null);
$namedGraph = $this->_request->getParam('named-graph-uri', null);
if (!empty($queryString)) {
$query = Erfurt_Sparql_SimpleQuery::initWithString($queryString);
// overwrite query-specidfied dataset with protocoll-specified dataset
if (null !== $defaultGraph) {
$query->setFrom((array)$defaultGraph);
}
if (null !== $namedGraph) {
$query->setFromNamed((array)$namedGraph);
}
// check graph availability
$ac = Erfurt_App::getInstance()->getAc();
foreach (array_merge($query->getFrom(), $query->getFromNamed()) as $graphUri) {
if (!$ac->isModelAllowed('view', $graphUri)) {
if (Erfurt_App::getInstance()->getAuth()->getIdentity()->isAnonymousUser()) {
// In this case we allow the requesting party to authorize...
$response->setRawHeader('HTTP/1.1 401 Unauthorized')
->setHeader('WWW-Authenticate', 'Basic realm="OntoWiki"')
->setHttpResponseCode(401);
return;
} else {
$response->setRawHeader('HTTP/1.1 500 Internal Server Error')
->setBody('QueryRequestRefused')
->setHttpResponseCode(500);
return;
}
}
}
$typeMapping = array(
'application/sparql-results+xml' => 'xml',
'application/json' => 'json',
'application/sparql-results+json' => 'json'
);
try {
$type = OntoWiki_Utils::matchMimetypeFromRequest($this->_request, array_keys($typeMapping));
} catch (Exeption $e) {
//
}
if (empty($type) && isset($this->_request->callback)) {
// JSONp
$type = 'application/sparql-results+json';
} else {
if (empty($type)) {
// default: XML
$type = 'application/sparql-results+xml';
}
}
try {
// get result for mimetype
$result = $store->sparqlQuery($query, array('result_format' => $typeMapping[$type]));
} catch (Exception $e) {
$response->setRawHeader('HTTP/1.1 400 Bad Request')
->setBody('MalformedQuery: ' . $e->getMessage())
->setHttpResponseCode(400);
return;
}
if (isset($this->_request->callback)) {
// return jsonp
$response->setHeader('Content-Type', 'application/javascript');
$padding = $this->_request->getParam('callback', '');
$response->setBody($padding . '(' . $result . ')');
} else {
// set header
$response->setHeader('Content-Type', $type);
// return normally
$response->setBody($result);
}
$response->setHttpResponseCode(200);
return;
}
}
/**
* OntoWiki Update Endpoint
*
* Only data inserts and deletes are implemented at the moment (e.g. no graph patterns).
*
* @todo LOAD <> INTO <>, CLEAR GRAPH <>, CREATE[SILENT] GRAPH <>, DROP[ SILENT] GRAPH <>
*/
public function updateAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$store = OntoWiki::getInstance()->erfurt->getStore();
$response = $this->getResponse();
$defaultGraph = $this->_request->getParam('default-graph-uri', null);
$namedGraph = $this->_request->getParam('named-graph-uri', null);
$insertGraph = null;
$deleteGraph = null;
$insertModel = null;
$deleteModel = null;
if (isset($this->_request->query)) {
// we have a query, enter SPARQL/Update mode
$query = $this->_request->getParam('query', '');
OntoWiki::getInstance()->logger->info('SPARQL/Update query: ' . $query);
$matches = array();
// insert
preg_match('/INSERT\s+DATA(\s+INTO\s*<(.+)>)?\s*{\s*([^}]*)/i', $query, $matches);
$insertGraph = (isset($matches[2]) && ($matches[2] !== '')) ? $matches[2] : null;
$insertTriples = isset($matches[3]) ? $matches[3] : '';
if ((null === $insertGraph) && ($insertTriples !== '')) {
if (null !== $defaultGraph) {
$insertGraph = $defaultGraph;
}
if (null !== $namedGraph) {
$insertGraph = $namedGraph;
}
}
OntoWiki::getInstance()->logger->info('SPARQL/Update insertGraph: ' . $insertGraph);
OntoWiki::getInstance()->logger->info('SPARQL/Update insertTriples: ' . $insertTriples);
// delete
preg_match('/DELETE\s+DATA(\s+FROM\s*<(.+)>)?\s*{\s*([^}]*)/i', $query, $matches);
$deleteGraph = (isset($matches[2]) && ($matches[2] !== '')) ? $matches[2] : null;
$deleteTriples = isset($matches[3]) ? $matches[3] : '';
if ((null === $deleteGraph) && ($deleteTriples !== '')) {
if (null !== $defaultGraph) {
$deleteGraph = $defaultGraph;
}
if (null !== $namedGraph) {
$deleteGraph = $namedGraph;
}
}
// TODO: normalize literals
$parser = Erfurt_Syntax_RdfParser::rdfParserWithFormat('nt');
$insert = $parser->parse($insertTriples, Erfurt_Syntax_RdfParser::LOCATOR_DATASTRING);
$parser->reset();
$delete = $parser->parse($deleteTriples, Erfurt_Syntax_RdfParser::LOCATOR_DATASTRING);
if (null !== $insertGraph) {
try {
$insertModel = $insertGraph ? $store->getModel($insertGraph) : $store->getModel($namedGraph);
} catch (Erfurt_Store_Exception $e) {
// TODO: error
if (defined('_OWDEBUG')) {
OntoWiki::getInstance()->logger->info('Could not instantiate models.');
}
return;
}
}
if (null !== $deleteGraph) {
try {
$deleteModel = $deleteGraph ? $store->getModel($deleteGraph) : $store->getModel($namedGraph);
} catch (Erfurt_Store_Exception $e) {
// TODO: error
if (defined('_OWDEBUG')) {
OntoWiki::getInstance()->logger->info('Could not instantiate models.');
}
return;
}
}
} else {
// no query, inserts and delete triples by JSON via param
$insert = json_decode($this->_request->getParam('insert', '{}'), true);
$delete = json_decode($this->_request->getParam('delete', '{}'), true);
if ($this->_request->has('delete_hashed')) {
$hashedObjectStatements = $this->_findStatementsForObjectsWithHashes(
$namedGraph,
json_decode($this->_request->getParam('delete_hashed'), true)
);
$delete = array_merge_recursive($delete, $hashedObjectStatements);
}
try {
$namedModel = $store->getModel($namedGraph);
$insertModel = $namedModel;
$deleteModel = $namedModel;
} catch (Erfurt_Store_Exception $e) {
// TODO: error
if (defined('_OWDEBUG')) {
OntoWiki::getInstance()->logger->info('Could not instantiate models.');
}
return;
}
}
$flag = false;
/**
* @trigger onUpdateServiceAction is triggered when Service-Controller Update Action is executed.
* Event contains following attributes:
* deleteModel : model to delete statments from
* deleteData : statements payload being deleted
* insertModel : model to add statements to
* insertData : statements payload being added
*/
$event = new Erfurt_Event('onUpdateServiceAction');
$event->deleteModel = $deleteModel;
$event->insertModel = $insertModel;
$event->deleteData = $delete;
$event->insertData = $insert;
$event->trigger();
// writeback
$delete = $event->deleteData;
$insert = $event->insertData;
$changes = isset($event->changes) ? $event->changes : null;
// delete
if ($deleteModel && $deleteModel->isEditable()) {
try {
$deleteModel->deleteMultipleStatements((array)$delete);
$flag = true;
if (defined('_OWDEBUG')) {
OntoWiki::getInstance()->logger->info(
sprintf('Deleted statements from graph <%s>', $deleteModel->getModelUri())
);
}
} catch (Erfurt_Store_Exception $e) {
if (defined('_OWDEBUG')) {
OntoWiki::getInstance()->logger->info(
'Could not delete statements from graph: ' . $e->getMessage() . PHP_EOL .
'Statements: ' . print_r($delete, true)
);
}
}
}
// insert
if ($insertModel && $insertModel->isEditable()) {
OntoWiki::getInstance()->logger->info(
'add Statements: ' . print_r($delete, true)
);
$count = $insertModel->addMultipleStatements($this->sanitizeStatements((array)$insert));
$flag = true;
if (defined('_OWDEBUG')) {
OntoWiki::getInstance()->logger->info(
sprintf('Inserted %i statements into graph <%s>', $count, $insertModel->getModelUri())
);
}
}
// nothing done?
if (!$flag) {
// When no user is given (Anoymous) give the requesting party a chance to authenticate.
if (Erfurt_App::getInstance()->getAuth()->getIdentity()->isAnonymousUser()) {
// In this case we allow the requesting party to authorize
$response->setRawHeader('HTTP/1.1 401 Unauthorized');
$response->setHeader('WWW-Authenticate', 'Basic realm="OntoWiki"');
return;
}
}
if ($changes) {
/**
* @see {http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.2}
*/
$response->setHttpResponseCode(201);
$response->setHeader('Location', $changes['changed']);
$response->setHeader('Content-Type', 'application/json');
$response->setBody(json_encode($changes));
}
}
/**
* Renders a template and responds with the output.
*
* All GET and POST parameters are populated into the view object
* and therefore available in the view script. You have to know
* which parameters the script uses and objects obviously cannot
* be passed via GET/POST.
*/
public function templateAction()
{
// fetch folder parameter
if (isset($this->_request->f)) {
$folder = $this->_request->getParam('f');
} else {
throw new OntoWiki_Exception('Missing parameter f!');
}
// fetch template parameter
if (isset($this->_request->t)) {
$template = $this->_request->getParam('t');
} else {
throw new OntoWiki_Exception('Missing parameter t!');
}
if (!preg_match('/^[a-z_]+$/', $folder) || !preg_match('/^[a-z_]+$/', $template)) {
throw new OntoWiki_Exception('Illegal characters in folder or template name!');
}
$path = _OWROOT . $this->_config->themes->path . $this->_config->themes->default . 'templates/' . $folder
. DIRECTORY_SEPARATOR;
$file = $template . '.' . $this->_helper->viewRenderer->getViewSuffix();
if (!is_readable($path . $file)) {
throw new OntoWiki_Exception('Template file not readable. ' . $path . $file);
}
// set script path
$this->view->setScriptPath($path);
// assign get and post parameters to view
$this->view->assign($this->_request->getParams());
// set header
$this->_response->setRawHeader('Content-type: text/html');
// render script
$this->_response->setBody($this->view->render($file));
}
/**
* JSON outputs of the transitive closure of resources to a given start
* resource and an transitive attribute
*/
public function transitiveclosureAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$store = OntoWiki::getInstance()->erfurt->getStore();
$response = $this->getResponse();
// fetch start resource parameter
if (isset($this->_request->sr)) {
$resource = $this->_request->getParam('sr', null, true);
} else {
throw new OntoWiki_Exception('Missing parameter sr (start resource)!');
}
// fetch property resource parameter
if (isset($this->_request->p)) {
$property = $this->_request->getParam('p', null, true);
} else {
throw new OntoWiki_Exception('Missing parameter p (property)!');
}
// m is automatically used and selected
if ((!isset($this->_request->m)) && (!$this->_owApp->selectedModel)) {
throw new OntoWiki_Exception('No model pre-selected model and missing parameter m (model)!');
} else {
$model = $this->_owApp->selectedModel;
}
// fetch inverse parameter
$inverse = $this->_request->getParam('inverse', 'true');
switch ($inverse) {
case 'false': /* fallthrough */
case 'no': /* fallthrough */
case 'off': /* fallthrough */
case '0':
$inverse = false;
break;
default:
$inverse = true;
}
$store = $model->getStore();
// get the transitive closure
$closure = $store->getTransitiveClosure((string)$model, $property, array($resource), $inverse);
// send the response
$response->setHeader('Content-Type', 'application/json');
$response->setBody(json_encode($closure));
}
/**
* JSON output of the RDFauthor selection Cache File of the current model or
* of the model given in parameter m
*/
public function rdfauthorcacheAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$store = OntoWiki::getInstance()->erfurt->getStore();
$response = $this->getResponse();
$model = $this->_owApp->selectedModel;
if (isset($this->_request->m)) {
$model = $store->getModel($this->_request->m);
}
if (empty($model)) {
throw new OntoWiki_Exception('Missing parameter m (model) and no selected model in session!');
}
$output = array();
$properties = $model->sparqlQuery(
'SELECT DISTINCT ?uri {
?uri a ?propertyClass.
FILTER(
sameTerm(?propertyClass, <' . EF_OWL_OBJECT_PROPERTY . '>) ||
sameTerm(?propertyClass, <' . EF_OWL_DATATYPE_PROPERTY . '>) ||
sameTerm(?propertyClass, <' . EF_OWL_ONTOLOGY_PROPERTY . '>) ||
sameTerm(?propertyClass, <' . EF_RDF_PROPERTY . '>)
)} LIMIT 200 '
);
if (!empty($properties)) {
// push all URIs to titleHelper
$titleHelper = new OntoWiki_Model_TitleHelper($model);
foreach ($properties as $property) {
$titleHelper->addResource($property['uri']);
}
$lastProperty = end($properties);
foreach ($properties as $property) {
$newProperty = array();
// return title from titleHelper
$newProperty['label'] = $titleHelper->getTitle($property['uri']);
$pdata = $model->sparqlQuery(
'SELECT DISTINCT ?key ?value
WHERE {
<' . $property['uri'] . '> ?key ?value
FILTER(
sameTerm(?key, <' . EF_RDF_TYPE . '>) ||
sameTerm(?key, <' . EF_RDFS_DOMAIN . '>) ||
sameTerm(?key, <' . EF_RDFS_RANGE . '>)
)
FILTER(isUri(?value))
}
LIMIT 20'
);
if (!empty($pdata)) {
$types = array();
$ranges = array();
$domains = array();
// prepare the data in arrays
foreach ($pdata as $data) {
if (($data['key'] == EF_RDF_TYPE) && ($data['value'] != EF_RDF_PROPERTY)) {
$types[] = $data['value'];
} elseif ($data['key'] == EF_RDFS_RANGE) {
$ranges[] = $data['value'];
} elseif ($data['key'] == EF_RDFS_DOMAIN) {
$domains[] = $data['value'];
}
}
if (!empty($types)) {
$newProperty['type'] = array_unique($types);
}
if (!empty($ranges)) {
$newProperty['range'] = array_unique($ranges);
}
if (!empty($domains)) {
$newProperty['domain'] = array_unique($domains);
}
}
$output[$property['uri']] = $newProperty;
}
}
// send the response
$response->setHeader('Content-Type', 'application/json');
$response->setBody(json_encode($output));
}
/**
* JSON output of the RDFauthor init config, which is a RDF/JSON Model
* without objects where the user should be able to add data
*
* get/post parameters:
* mode - class, resource or clone
* class: prop list based on one class' resources
* resource: prop list based on one resource
* clone: prop list and values based on one resource (with new uri)
* edit: prop list and values based on one resource
* uri - parameter for mode (class uri, resource uri)
*/
public function rdfauthorinitAction()
{
// service controller needs no view renderer
$this->_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$store = OntoWiki::getInstance()->erfurt->getStore();
$response = $this->getResponse();
$model = $this->_owApp->selectedModel;
if (isset($this->_request->m)) {
$model = $store->getModel($this->_request->m);
}
if (empty($model)) {
throw new OntoWiki_Exception('Missing parameter m (model) and no selected model in session!');
}
if ((isset($this->_request->uri)) && (Zend_Uri::check($this->_request->uri))) {
$parameter = $this->_request->uri;
} else {
throw new OntoWiki_Exception('Missing or invalid parameter uri (clone uri) !');
}
if (isset($this->_request->mode)) {
$workingMode = $this->_request->mode;
} else {
$workingMode = 'resource';
}
if ($workingMode != 'edit') {
$resourceUri = $model->getBaseUri() . 'newResource/' . md5(date('F j, Y, g:i:s:u a'));
} else {
$resourceUri = $parameter;
}
if ($workingMode == 'class') {
$properties = $model->sparqlQuery(
'SELECT DISTINCT ?uri ?value {
?s ?uri ?value.
?s a <' . $parameter . '>.
} LIMIT 20 ', array('result_format' => 'extended')
);
} elseif ($workingMode == 'clone') {
// FIXME: more than one values of a property are not supported right now
// FIXME: Literals are not supported right now
$properties = $model->sparqlQuery(
'SELECT ?uri ?value {
<' . $parameter . '> ?uri ?value.
#FILTER (isUri(?value))
} LIMIT 20 ', array('result_format' => 'extended')
);
} elseif ($workingMode == 'edit') {
$properties = $model->sparqlQuery(
'SELECT ?uri ?value {
<' . $parameter . '> ?uri ?value.
} LIMIT 20 ', array('result_format' => 'extended')
);
} else { // resource
$properties = $model->sparqlQuery(
'SELECT DISTINCT ?uri ?value {
<' . $parameter . '> ?uri ?value.
} LIMIT 20 ', array('result_format' => 'extended')
);
}
// empty object to hold data
$output = new stdClass();
$newProperties = new stdClass();
$properties = $properties['results']['bindings'];
// feed title helper w/ URIs
$titleHelper = new OntoWiki_Model_TitleHelper($model);
$titleHelper->addResources($properties, 'uri');
if (!empty($properties)) {
foreach ($properties as $property) {
$currentUri = $property['uri']['value'];
$currentValue = $property['value']['value'];
$currentType = $property['value']['type'];
$value = new stdClass();
if ($currentType == 'literal' || $currentType == 'typed-literal') {
if (isset($property['value']['datatype'])) {
$value->datatype = $property['value']['datatype'];
} else {
if (isset($property['value']['xml:lang'])) {
$value->lang = $property['value']['xml:lang'];
}
}
}
// return title from titleHelper
$value->title = $titleHelper->getTitle($currentUri);
if ($currentUri == EF_RDF_TYPE) {
switch ($workingMode) {
case 'resource':
/* fallthrough */
case 'clone':
$value->value = $currentValue;
break;
case 'edit':
$value->value = $currentValue;
break;
case 'class':
$value->value = $parameter;
break;
}
$value->type = $currentType;
} else { // $currentUri != EF_RDF_TYPE
if (($workingMode == 'clone') || ($workingMode == 'edit')) {
$value->value = $currentValue;
$value->type = $currentType;
}
if ($workingMode == 'class') {
$value->value = '';
$value->type = $currentType;
}
}
// deal with multiple values of a property
if (isset($newProperties->$currentUri)) {
$tempProperty = $newProperties->$currentUri;
$tempProperty[] = $value;
$newProperties->$currentUri = $tempProperty;
} else {
$newProperties->$currentUri = array($value);
}
} // foreach
$output->$resourceUri = $newProperties;
} else {
// empty sparql results -> start with a plain resource
if ($workingMode == 'class') {
// for classes, add the rdf:type property
$value = new stdClass();
$value->value = $parameter;
$value->type = 'uri';
$value->hidden = true;
$uri = EF_RDF_TYPE;
$newProperties->$uri = array($value);
}
$value = new stdClass();
$value->type = 'literal';
$value->title = 'label';
$uri = EF_RDFS_LABEL;
$newProperties->$uri = array($value);
$output->$resourceUri = $newProperties;
}
// send the response
$response->setHeader('Content-Type', 'application/json');
$response->setBody(json_encode($output));
}
protected function _findStatementsForObjectsWithHashes($graphUri, $indexWithHashedObjects, $hashFunc = 'md5')
{
$queryOptions = array(
'result_format' => 'extended'
);
$result = array();
foreach ($indexWithHashedObjects as $subject => $predicates) {
foreach ($predicates as $predicate => $hashedObjects) {
$query = "SELECT ?o FROM <$graphUri> WHERE {<$subject> <$predicate> ?o .}";
$queryObj = Erfurt_Sparql_SimpleQuery::initWithString($query);
if ($queryResult = $this->_owApp->erfurt->getStore()->sparqlQuery($queryObj, $queryOptions)) {
$bindings = $queryResult['results']['bindings'];
for ($i = 0, $max = count($bindings); $i < $max; $i++) {
$currentObject = $bindings[$i]['o'];
$objectString = Erfurt_Utils::buildLiteralString(
$currentObject['value'],
isset($currentObject['datatype']) ? $currentObject['datatype'] : null,
isset($currentObject['xml:lang']) ? $currentObject['xml:lang'] : null
);
$hash = $hashFunc($objectString);
if (in_array($hash, $hashedObjects)) {
// add current statement to result
if (!isset($result[$subject])) {
$result[$subject] = array();
}
if (!isset($result[$subject][$predicate])) {
$result[$subject][$predicate] = array();
}
$objectSpec = array(
'value' => $currentObject['value'],
'type' => str_replace('typed-', '', $currentObject['type'])
);
if (isset($currentObject['datatype'])) {
$objectSpec['datatype'] = $currentObject['datatype'];
} else {
if (isset($currentObject['xml:lang'])) {
$objectSpec['lang'] = $currentObject['xml:lang'];
}
}
array_push($result[$subject][$predicate], $objectSpec);
}
}
}
}
}
return $result;
}
/**
* Removes all statements whose object has an empty URI.
*
* Seems as if these kind of statements are sometimes provided by the RDFAuthor editor.
*
* @param array(string=>array(string=>array(string=>string))) $statements
* @return array(string=>array(string=>array(string=>string)))
*/
protected function sanitizeStatements(array $statements)
{
foreach (array_keys($statements) as $subject) {
/* @var $subject string */
foreach (array_keys($statements[$subject]) as $predicate) {
/* @var $predicate string */
foreach ($statements[$subject][$predicate] as $index => $objectSpec) {
/* @var $index integer */
/* @var $objectSpec array(string=>string) */
if ($objectSpec['type'] === 'uri' && empty($objectSpec['value'])) {
// Empty URIs are not allowed, remove this statement from the list.
unset($statements[$subject][$predicate][$index]);
}
}
}
}
return $statements;
}
}
================================================
FILE: application/scripts/README-Vagrant.md
================================================
Getting Started
---------------
1. Install VirtualBox [1] + Vagrant [2]
2. Install vbguest plugin for Vagrant: `vagrant gem install vagrant-vbguest`
3. Add the following to your `/etc/hosts` file
192.168.33.10 ontowiki.local
192.168.33.10 phpmyadmin.ontowiki.local
4. Run `make vagrant` (only the first time) afterwards use `vagrant up`
- [1] https://www.virtualbox.org
- [2] http://vagrantup.com
5. Just type `http://192.168.33.10` into your browser
================================================
FILE: application/scripts/clearCache.php
================================================
#!/usr/bin/env php
*/
/*
* error handling for the very first includes etc.
* http://stackoverflow.com/questions/1241728/
*/
function errorHandler ($errno, $errstr, $errfile, $errline, array $errcontext)
{
// error was suppressed with the @-operator
if (0 === error_reporting()) {
return false;
}
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
/*
* method to get evironment variables which are prefixed with "REDIRECT_"
* in some configurations Apache prefixes the environment variables on each rewrite walkthrough
* e.g. under centos
*/
function getEnvVar ($key)
{
$prefix = "REDIRECT_";
if (isset($_SERVER[$key])) {
return $_SERVER[$key];
}
foreach ($_SERVER as $k => $v) {
if (substr($k, 0, strlen($prefix)) == $prefix) {
if (substr($k, -(strlen($key))) == $key) {
return $v;
}
}
}
return null;
}
function initApp(){
/* Profiling */
define('REQUEST_START', microtime(true));
set_error_handler('errorHandler');
/**
* Bootstrap constants
* @since 0.9.5
*/
if (!defined('__DIR__')) {
define('__DIR__', dirname(__FILE__));
} // fix for PHP < 5.3.0
define('BOOTSTRAP_FILE', basename(__FILE__));
define('ONTOWIKI_ROOT', rtrim(dirname(dirname(__DIR__)), '/\\') . DIRECTORY_SEPARATOR);
define('APPLICATION_PATH', ONTOWIKI_ROOT . 'application'.DIRECTORY_SEPARATOR);
define('CACHE_PATH', ONTOWIKI_ROOT . 'cache'.DIRECTORY_SEPARATOR);
/**
* Old constants for < 0.9.5 backward compatibility
* @deprecated 0.9.5
*/
define('_OWBOOT', BOOTSTRAP_FILE);
define('_OWROOT', ONTOWIKI_ROOT);
define('OW_SHOW_MAX', 5);
// PHP environment settings
ini_set('max_execution_time', 240);
if ((int)substr(ini_get('memory_limit'), 0, -1) < 256) {
ini_set('memory_limit', '256M');
}
/*
* include path preparation
*/
// init with local path in order to prefer these over system paths
$includePath = ONTOWIKI_ROOT . 'libraries/' . PATH_SEPARATOR;
// append local Erfurt include path
if (file_exists(ONTOWIKI_ROOT . 'libraries/Erfurt/Erfurt/App.php')) {
$includePath .= ONTOWIKI_ROOT . 'libraries/Erfurt/' . PATH_SEPARATOR;
} else if (file_exists(ONTOWIKI_ROOT . 'libraries/Erfurt/library/Erfurt/App.php')) {
$includePath .= ONTOWIKI_ROOT . 'libraries/Erfurt/library' . PATH_SEPARATOR;
}
// append system include paths
$includePath .= get_include_path() . PATH_SEPARATOR;
// set the include path
set_include_path($includePath);
// use default timezone from php.ini or let PHP guess it
date_default_timezone_set(@date_default_timezone_get());
// determine wheter rewrite engine works
// and redirect to a URL that doesn't need rewriting
// TODO: check for AllowOverride All
$rewriteEngineOn = false;
define('ONTOWIKI_REWRITE', $rewriteEngineOn);
/** check/include Zend_Application */
try {
// use include, so we can catch it with the error handler
require_once 'Zend/Application.php';
} catch (Exception $e) {
header('HTTP/1.1 500 Internal Server Error');
echo 'Fatal Error: Could not load Zend library. ' . PHP_EOL
. 'Maybe you need to install it with apt-get or with "make zend"?' . PHP_EOL;
exit;
}
// create application
$application = new Zend_Application(
'default',
ONTOWIKI_ROOT . 'application/config/application.ini'
);
/** check/include OntoWiki */
try {
// use include, so we can catch it with the error handler
require_once 'OntoWiki.php';
} catch (Exception $e) {
print('Fatal Error: Could not load the OntoWiki Application Framework classes.' . PHP_EOL);
print('Your installation directory seems to be screwed.' . PHP_EOL);
exit;
}
/* check/include Erfurt_App */
try {
// use include, so we can catch it with the error handler
require_once 'Erfurt/App.php';
} catch (Exception $e) {
print('Fatal Error: Could not load the Erfurt Framework classes.' . PHP_EOL);
print('Maybe you should install it with apt-get or with "make deploy"?' . PHP_EOL);
exit;
}
// restore old error handler
restore_error_handler();
// bootstrap
try {
$application->bootstrap();
} catch (Exception $e) {
print('Error on bootstrapping application: ' . $e->getMessage() . PHP_EOL);
exit;
}
return $application;
}
chdir ("../..");
initApp();
$erfurt = Erfurt_App::getInstance();
$erfurt->getCache()->clean();
$erfurt->getQueryCache()->cleanUpCache(array('mode' => 'uninstall'));
#if (Zend_Translate::hasCache()) {
# Zend_Translate::clearCache();
#}
================================================
FILE: application/scripts/extensions-ini2n3.php
================================================
$val) {
if (is_array($val)) {
$string .= INI::write_get_string($ini[$key], $prefix.$key.'.');
} else {
$string .= $prefix.$key.' = '.str_replace("\n", "\\\n", INI::set_value($val))."\n";
}
}
return $string;
}
/**
* manage keys
*/
static function set_value($val) {
if ($val === true) { return 'true'; }
else if ($val === false) { return 'false'; }
return $val;
}
/**
* READ
*/
static function read($filename) {
$ini = array();
$lines = file($filename);
$section = 'default';
$multi = '';
foreach($lines as $line) {
if (substr($line, 0, 1) !== ';') {
$line = str_replace("\r", "", str_replace("\n", "", $line));
$line = preg_replace('/"(\s*);(.*)$/', '"', $line); //remove comment after value
$line = preg_replace('/\'(\s*);(.*)$/', '\'', $line); //remove comment after value
if (preg_match('/^\[(.*)\]/', $line, $m)) {
$section = $m[1];
} else if ($multi === '' && preg_match('/^([a-z0-9_.\[\]-]+)\s*=\s*(.*)$/i', $line, $m)) {
$key = $m[1];
$val = $m[2];
if (substr($val, -1) !== "\\") {
$val = trim($val);
INI::manage_keys($ini[$section], $key, $val);
$multi = '';
} else {
$multi = substr($val, 0, -1)."\n";
}
} else if ($multi !== '') {
if (substr($line, -1) === "\\") {
$multi .= substr($line, 0, -1)."\n";
} else {
INI::manage_keys($ini[$section], $key, $multi.$line);
$multi = '';
}
}
}
}
return $ini;
}
/**
* manage keys
*/
static function get_value($val) {
if (preg_match('/^-?[0-9]*$/i', $val)) { return intval($val); }
else if (strtolower($val) === 'yes') { return true; }
else if (strtolower($val) === 'true') { return true; }
else if (strtolower($val) === 'no') { return false; }
else if (strtolower($val) === 'false') { return false; }
else if (preg_match('/^"(.*)"$/i', $val, $m)) { return $m[1]; }
else if (preg_match('/^\'(.*)\'$/i', $val, $m)) { return $m[1]; }
//unquoted string, remove comments and trim
$cPos = strpos($val, ';');
if($cPos === false ){
return trim($val);
} else {
return trim(substr($val, 0, $cPos));
}
}
/**
* manage keys
*/
static function get_key($val) {
if (preg_match('/^[0-9]$/i', $val)) { return intval($val); }
return $val;
}
/**
* manage keys
*/
static function manage_keys(& $ini, $key, $val) {
if (preg_match('/^([a-z0-9_-]+)\.(.*)$/i', $key, $m)) {
INI::manage_keys($ini[$m[1]], $m[2], $val);
} else if (preg_match('/^([a-z0-9_-]+)\[(.*)\]$/i', $key, $m)) {
if ($m[2] !== '') {
$ini[$m[1]][INI::get_key($m[2])] = INI::get_value($val);
} else {
$ini[$m[1]][] = INI::get_value($val);
}
} else {
$ini[INI::get_key($key)] = INI::get_value($val);
}
}
/**
* replace utility
*/
static function replace_consts(& $item, $key, $consts) {
if (is_string($item)) {
$item = strtr($item, $consts);
}
}
}
class ExtensionSerializer
{
private $_map = array(
'name' => array(
'type'=>'literal',
'property'=>'rdfs:label'
),
'enabled' =>array(
'type'=>'literal',
'property'=>'owconfig:enabled',
'datatype' => 'boolean'
),
'author' =>array(
'type'=>'literal',
'property'=>'owconfig:authorLabel'
),
'templates' =>array(
'type'=>'literal',
'property'=>'owconfig:templates'
),
'languages' =>array(
'type'=>'literal',
'property'=>'owconfig:languages'
),
'helpers' =>array(
'type'=>'literal',
'property'=>'owconfig:helpers'
),
'caching' =>array(
'type'=>'literal',
'property'=>'owconfig:caching',
'datatype' => 'boolean'
),
'priority' =>array(
'type'=>'literal',
'property'=>'owconfig:priority'
),
'description' =>array(
'type'=>'literal',
'property'=>'doap:description'
),
'contexts' =>array(
'type'=>'literal',
'property'=>'owconfig:context'
),
'title' =>array(
'type'=>'literal',
'property'=>'rdfs:label'
),
'classes' =>array(
'type'=>'literal',
'property'=>'owconfig:class'
),
'action' =>array(
'type'=>'literal',
'property'=>'owconfig:defaultAction'
),
'authorUrl' =>array(
'type'=>'uri',
'property'=>'doap:maintainer',
)
);
private $_lastSubject = null;
private $_bnCounter = 0;
private $_parent = null;
private $_depth = 0;
function resetLastSubject()
{
echo ' .'.PHP_EOL;
$this->_lastSubject = null;
}
function addBN($subj, $prop)
{
$bn = $this->_bnCounter++;
$bn = '_:'.$bn;
//echo "start bn for ".$prop." bn=".$bn.PHP_EOL;
$this->printStatement($subj, $prop, '[');
$this->_parent = $this->_lastSubject;
$this->_lastSubject = $bn;
$this->_depth++;
return $bn;
}
function endBN($uri = null)
{
/*if($uri != null){
if($uri != $this->_lastSubject){
return; //do not end this, this is not what you wanted to end
}
}*/
//$this->flush();
$this->_depth--;
$i = str_repeat(' ', $this->_depth);
echo PHP_EOL.$i.']';
$this->_lastSubject = $this->_parent;
}
function getObject($property, $value)
{
if (is_string($value)) {
$value = addslashes($value);
}
if ((isset($this->_map[$property]) && $this->_map[$property]['type'] == 'uri') || Erfurt_Uri::check($value)) {
$object = '<'.$value.'>';
} else if (is_bool($value)) {
$object = '"'.($value ? 'true' : 'false').'"^^xsd:boolean';
} else if (is_string($value) && $value == 'true' || $value == 'false') {
$object = '"'.($value == 'true' ? 'true' : 'false').'"^^xsd:boolean'; //why?
} else if (isset($this->_map[$property]['datatype']) && $this->_map[$property]['datatype'] == 'boolean') {
$object = '"'.((bool)$value ? 'true' : 'false').'"^^xsd:boolean';
} else {
$object = '"'.$value.'"';
}
return $object;
}
function getPredicate($property, $sectionname)
{
return (
(!isset($this->_map[$property]) || $sectionname == 'private') ?
':'.$property :
$this->_map[$property]['property']
);
}
function printStatement($s, $p, $o)
{
//indent
$i = str_repeat(' ', $this->_depth);
/*if (substr($this->_lastSubject, 0, 2) == '_:' && substr($s, 0, 2) != '_:') {
//echo substr($s, 0, 2).PHP_EOL;
//echo "end bn implicitly. old: ".$this->_lastSubject. " s: $s p: $p o:$o".PHP_EOL;
$this->endBN($this->_lastSubject);
}*/
if ($this->_lastSubject == null) {
$this->_lastSubject = $s;
echo $i.$s.' '. $p .' '.$o;
} else if ($this->_lastSubject == $s) {
echo ' ;'.PHP_EOL.$i.' '. $p .' '.$o;
} else {
$this->_lastSubject = $s;
echo ' .'.PHP_EOL.$i.$s.' '. $p .' '.$o;
}
}
function __destruct()
{
$this->flush();
}
function flush()
{
echo ' .'.PHP_EOL;
}
}
class NestedPropertyAndModuleHandler
{
public $modules = array();
public $properties = array();
/**
*
* @var ExtensionSerializer
*/
private $_printer = null;
private $_subject = null;
private $_parent = null;
function __construct(ExtensionSerializer $_printer, $_subj)
{
$this->_printer = $_printer;
$this->_subject = $_subj;
}
function printProperty($name, $value)
{
$this->_parent = $this->_subject;
$bnUri = $this->_printer->addBN($this->_subject, 'owconfig:config');
$this->_subject = $bnUri;
$this->_printer->printStatement($bnUri, 'a', 'owconfig:Config;');
$this->_printer->printStatement($bnUri, 'owconfig:id', '"'.$name.'";');
//$this->_printer->printStatement($bnUri, 'rdfs:comment', '"fixme";');
foreach ($value as $subKey => $subValue) {
if (!is_array($subValue)) {
$this->_printer->printStatement(
$bnUri,
$this->_printer->getPredicate($subKey, ''),
$this->_printer->getObject($subKey, $subValue)
);
} else {
if (!self::is_numeric($subValue)) {
$this->printProperty($subKey, $subValue);
} else {
foreach ($subValue as $subSubKey => $subSubValue) {
if (!is_array($subSubValue)) {
$this->_printer->printStatement(
$bnUri,
$this->_printer->getPredicate($subKey, ''), //omit the $subSubKey here!
$this->_printer->getObject($subKey, $subSubValue)
);
} else {
$this->printProperty($subKey, $subValue);
}
}
}
}
}
$this->_printer->endBN($bnUri);
}
static private function is_assoc ($arr)
{
return (is_array($arr) && count(array_filter(array_keys($arr), 'is_string')) == count($arr));
}
static private function is_numeric ($arr)
{
return (is_array($arr) && count(array_filter(array_keys($arr), 'is_int')) == count($arr));
}
function printN3()
{
foreach ($this->modules as $name => $config) {
//print a module
$moduleUri = ':'.ucfirst($name);
$this->_printer->printStatement($this->_subject, 'owconfig:hasModule', $moduleUri);
$this->_printer->printStatement($moduleUri, 'a', 'owconfig:Module');
if (!isset($config['title'])) {
$this->_printer->printStatement($moduleUri, 'rdfs:label', '"'.ucfirst($name).'"');
}
foreach ($config as $prop => $val) {
if (!is_array(($val))) {
$this->_printer->printStatement(
$moduleUri,
$this->_printer->getPredicate($prop, ''),
$this->_printer->getObject($prop, $val)
);
} else {
foreach ($val as $subval) { //recursion is not needed (?)
$this->_printer->printStatement(
$moduleUri,
$this->_printer->getPredicate($prop, ''),
$this->_printer->getObject($prop, $subval)
);
}
}
}
$this->_printer->resetLastSubject();
}
if (is_array($this->properties)) {
foreach ($this->properties as $name => $value) {
if (is_array($value)) {
if (self::is_numeric($value)) {
foreach ($value as $subval) {
$this->_printer->printStatement(
$this->_subject,
$this->_printer->getPredicate($name, 'private'),
$this->_printer->getObject($name, $subval)
);
}
} else {
$this->printProperty($name, $value, 1, null);
}
} else {
$this->_printer->printStatement(
$this->_subject,
$this->_printer->getPredicate($name, 'private'),
$this->_printer->getObject($name, $value)
);
}
}
}
}
}
class Converter
{
static function convert($iniPath, $extension)
{
ob_start();
$privNS = "https://github.com/AKSW/$extension/raw/master/doap.n3#";
//!!!!REMOVE THIS LINE AFTER YOU HAVE REVIEWED/FIXED THIS FILE!!!!
echo <<.
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : <$privNS> .
EOT;
require_once __DIR__.'/../../libraries/Zend/Config.php';
require_once __DIR__.'/../../libraries/Zend/Config/Ini.php';
$config = INI::read($iniPath);
//var_dump($config);
if(!isset($config['default'])){
$config['default'] = array();
}
foreach ($config as $sectionname => $sectionconf) {
if(!in_array($sectionname, array('default','events', 'private'))){
$config['default'][$sectionname] = $sectionconf;
unset($config[$sectionname]);
}
}
//var_dump($config); exit;
$subject = ':'.$extension;
$es = new ExtensionSerializer();
$es->printStatement('<>', 'foaf:primaryTopic', $subject);
$es->printStatement($subject, 'a', 'doap:Project');
$es->printStatement($subject, 'doap:name', '"'.$extension.'"');
$es->printStatement($subject, 'owconfig:privateNamespace', '<'.$privNS.'>');
$mp = new NestedPropertyAndModuleHandler($es, $subject);
foreach ($config as $sectionname => $sectionconf) {
if ($sectionname == 'private') {
$mp->properties = $sectionconf;
continue;
}
if (is_array($sectionconf)) {
foreach ($sectionconf as $property => $value) {
if ($property == 'modules') {
$mp->modules = array_merge_recursive($mp->modules, $value);
continue;
} else if ($property == 'priority' || $property == 'contexts'
|| $property == 'caching' || $property == 'title') {
$mp->modules = array_merge_recursive(
$mp->modules,
array('default'=>(array($property=>$value)))
);
} else if ($sectionname == 'default' && $property == 'helperEvents') {
$predicate = 'owconfig:helperEvent';
if(is_array($value)){
foreach ($value as $v){
$object = 'event:'.$v;
$es->printStatement($subject, $predicate, $object);
}
} else {
$object = 'event:'.$value;
$es->printStatement($subject, $predicate, $object);
}
} else if ($sectionname == 'events') {
$predicate = 'owconfig:pluginEvent';
if(is_array($value)){
foreach ($value as $v){
$object = 'event:'.$v;
$es->printStatement($subject, $predicate, $object);
}
} else {
$object = 'event:'.$value;
$es->printStatement($subject, $predicate, $object);
}
} else {
//this is not in global section and not in events
$predicate = $es->getPredicate($property, $sectionname);
if (is_array($value)) {
//should never happen
} else {
$object = $es->getObject($property, $value);
$es->printStatement($subject, $predicate, $object);
}
}
}
} else {
//parsing a property that has no section -> global section (the first lines until the first section)
$property = $sectionname;
$value = $sectionconf;
$predicate = $es->getPredicate($property, $sectionname);
$object = $es->getObject($property, $value);
$es->printStatement($subject, $predicate, $object);
}
}
$mp->printN3();
$version = ':v1-0';
$es->printStatement($subject, 'doap:release', $version);
$es->printStatement($version, 'a', 'doap:Version');
$es->printStatement($version, 'doap:revision', '"1.0"');
//make sure the destructors are called
$es = null;
$mp = null;
$res = ob_get_clean();
//some wtf fixes :)
$res = str_replace(";;", ";", $res);
$res = str_replace("[;", "[", $res);
$res = str_replace("; ;", ";", $res);
$res = str_replace("[ ;", "[", $res);
$res = preg_replace("/\\]\s*\.?\n\s*_:[0-9]*/", "];\n", $res);
$res = preg_replace("/.\n\s*_:[0-9]*/", ";\n", $res);
return $res;
}
}
//script
$path = realpath(__DIR__.'/../../libraries/');
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
require_once realpath(__DIR__.'/../../libraries/Erfurt/library/Erfurt/Uri.php');
if ($argc > 4) {
echo 'usage: extensions-ini2n3.sh []'.PHP_EOL; exit(-1);
} else {
if ($argc==2) {
echo Converter::convert(__DIR__.'/../../extensions/'.$argv[1].'/default.ini', $argv[1]);
} else if ($argc==4) {
$in = $argv[1];
$out = $argv[2];
$name = $argv[3];
$newContent = Converter::convert($in, $name);
file_put_contents($out, $newContent);
} else {
$dir = realpath(__DIR__.'/../../extensions/');
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
$fullPath = realpath($dir.DIRECTORY_SEPARATOR.$file);
if (
$file != "." && $file != ".." && $file != "themes" &&
$file != "translations" && is_dir($fullPath) && is_writable($fullPath)
) {
//echo $file.PHP_EOL;
$origIni = realpath($fullPath.DIRECTORY_SEPARATOR.'default.ini');
if (file_exists($origIni) && is_readable($origIni)) {
$newFile = $fullPath."/doap.n3";
echo "write ".$newFile.PHP_EOL;
file_put_contents($newFile, Converter::convert($origIni, $file));
} else {
echo 'no default.ini in '.$fullPath.PHP_EOL;
}
} else {
echo 'skipping non-extension dir '.$fullPath.PHP_EOL;
}
}
closedir($handle);
}
}
}
================================================
FILE: application/scripts/makeBackup.sh
================================================
#!/bin/sh
for model in `owcli -l`
do
filename=`echo "$model" | md5sum | cut -d " " -f 1`
owcli -m "$model" -e model:export >$filename.rdf
done
================================================
FILE: application/scripts/makeRelease.sh
================================================
#!/bin/bash
# @(#) Creates an OntoWiki Release ZIP File
parameter="$1"
if [ "$parameter" == "" ]
then
echo "No Version Parameter (e.g. 0.9.5)!"
exit 1;
fi
releaseDirBase="ontowiki-$parameter"
releaseZIP="./$releaseDirBase.zip"
releaseDir="/tmp/$releaseDirBase"
OWHG="https://ontowiki.googlecode.com/hg/"
if [ -e "$releaseDir" ]
then
echo "There exists a Directory $releaseDir"
echo "Delete by hand and start again ..."
exit 1
fi
if [ ! -e "$releaseDir" ]
then
echo "Checkout $OWHG to $releaseDir"
hg --config web.cacerts= clone $OWHG $releaseDir || exit
else
echo "Try to update $releaseDir (or exit on failure)"
hg --config web.cacerts= pull $releaseDir || exit
fi
cd $releaseDir
echo "update to OntoWiki-$parameter"
hg --config web.cacerts= update OntoWiki-$parameter || exit
make update
echo "Delete unwanted files and directories in $releaseDir"
#rm -rf `find $releaseDir -name '.svn'`
rm -rf $releaseDir/.hg
rm -rf $releaseDir/extensions.ext
echo "Create and copy additional files and directories in $releaseDir"
mkdir $releaseDir/cache $releaseDir/logs $releaseDir/uploads
chmod 777 $releaseDir/cache $releaseDir/logs $releaseDir/uploads
chmod 777 extensions
echo "Download and unpack a Zend Framework"
cd $releaseDir && make zend
echo "Create the ZIP ~/$releaseDirBase.zip"
cd $releaseDir/.. && zip -q -9 -r ~/$releaseDirBase.zip $releaseDirBase
echo "Create the tar.gz ~/$releaseDirBase.tar.gz"
cd $releaseDir/.. && tar czf ~/$releaseDirBase.tar.gz $releaseDirBase
echo "Create the 7zip ~/$releaseDirBase.7z"
cd $releaseDir/.. && 7zr a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=on ~/$releaseDirBase.7z $releaseDirBase >/dev/null
echo "Create the ZIP ~/$releaseDirBase-without-Zend.zip"
rm -rf $releaseDir/libraries/Zend/ && cd $releaseDir/.. && zip -q -9 -r ~/$releaseDirBase-without-Zend.zip $releaseDirBase
echo "Delete the release dir"
rm -rf $releaseDir
================================================
FILE: application/scripts/mod-auth-external/ontowiki.php
================================================
#!/usr/bin/env php5
registerNamespace('Erfurt_');
// session is needed for authentication
$session = new Zend_Session_Namespace('OntoWiki_mod-auth-external_Authenticator');
// Parse the OntoWiki configuration
$config = new Zend_Config_Ini(ONTOWIKI_ROOT . 'config.ini', 'private');
// start the Erfurt engine (with a specific config)
$app = Erfurt_App::getInstance(false);
$app->start($config);
// grab the user/pass from php://stdin
$stdin = file_get_contents ( 'php://stdin');
// split the input by EOL
$userpass = explode( PHP_EOL, $stdin);
// set and check username
if ( (isset($userpass[0])) && ($userpass[0] != '') ) {
$user = $userpass[0];
} else {
echo "No user given" . PHP_EOL;
exit (1);
}
// set password
if ( isset($userpass[1]) ) {
$pass = $userpass[1];
} else {
$pass = '';
}
// Try to authenticate the user
// http://files.zend.com/help/Zend-Framework/zend.auth.html#zend.auth.introduction.results
$authResult = $app->authenticate($user, $pass);
// return 0 or 1 (message output on error)
if ($authResult->getCode() == Zend_Auth_Result::SUCCESS) {
exit (0);
} else {
foreach ($authResult->getMessages() as $message) {
echo "(User: $user) $message" . PHP_EOL;
}
exit (1);
}
================================================
FILE: application/scripts/odbctest.php
================================================
#! /usr/bin/env php
'Import files in data directory into Virtuoso',
'virtclear' => 'Clear a specified graph',
'help|h' => 'Help -- usage message',
));
try {
$getopt->parse();
} catch (Zend_Console_Getopt_Exception $e) {
// Bad options passed: report usage
echo $e->getUsageMessage();
return false;
}
// If help requested, report usage message
if ($getopt->getOption('h')) {
echo $getopt->getUsageMessage();
return true;
} else if ($getopt->getOption('virtload')) {
return _importData();
} else if ($getopt->getOption('virtclear')) {
return _clearGraph();
} else {
echo $getopt->getUsageMessage();
return true;
}
return true;
/* Functions */
function _clearGraph()
{
$graph = _chooseGraph();
if (!$graph) {
return false;
}
$command = "isql VERBOSE=OFF \"EXEC=sparql DELETE FROM <$graph> {?s ?p ?o} WHERE {?s ?p ?o}\" 2>&1 1> /dev/null";
$output = shell_exec($command);
if (null !== $output) {
return false;
}
echo "DONE!" . PHP_EOL;
return true;
}
function _importData()
{
// Check for files
$importFiles = array();
$files = scandir(SCRIPT_DIR . 'data');
foreach ($files as $file) {
if ($file[0] === '.') {
continue;
}
$importFiles[$file] = SCRIPT_DIR . 'data' . DIRECTORY_SEPARATOR . $file;
}
$failed = false;
$failReason = '';
foreach ($importFiles as $file=>$fullPath) {
$ending = substr($file, -4);
switch ($ending) {
case '.ttl':
break;
case '.owl':
case '.rdf':
$newPath = SCRIPT_DIR . 'tmp' . DIRECTORY_SEPARATOR . 'sourceNtriples.ttl';
$cmd = "rapper -gqo ntriples '$fullPath' 2>&1 1> /dev/null > '$newPath'";
$output = shell_exec($cmd);
if (null !== $output) {
echo 'Error while converting source file to TTL.';
return;
}
$fullPath = $newPath;
break;
default:
continue;
}
echo "Preparing import of file $file now." . PHP_EOL;
$graph = _chooseGraph();
if (!$graph) {
$failed = true;
$failReason = 'Invalid Graph!';
break;
}
echo "Will import data into graph <$graph>." . PHP_EOL;
$splitFiles = _splitFiles($fullPath);
$count = count($splitFiles);
foreach ($splitFiles as $i=>$splitFile) {
$progress = round(($i/$count)*100.0);
echo "\rImporting $file now: $progress%";
if (!$failed) {
$result = _importFile($splitFile, $graph);
}
unlink($splitFile);
if (!$result) {
$failed = true;
$failReason = 'Import failed';
}
}
// Move file to done dir!
if (!$failed) {
copy($fullPath, SCRIPT_DIR.'done'.DIRECTORY_SEPARATOR.$file);
unlink($fullPath);
}
echo PHP_EOL;
}
if ($failed) {
echo $failReason . PHP_EOL;
} else {
echo 'DONE!' . PHP_EOL;
}
return true;
}
function _splitFiles($fullPath)
{
$splitFiles = array();
$fHandle = fopen($fullPath, 'r');
$fileCount = 0;
$i = 0;
$currentContent = '';
if ($fHandle) {
while ($line = fgets($fHandle)) {
$currentContent .= $line;
$i++;
if ($i === 10000) {
$tmp = SCRIPT_DIR . 'tmp' . DIRECTORY_SEPARATOR . $fileCount++;
file_put_contents($tmp, $currentContent);
$splitFiles[] = $tmp;
$i = 0;
$currentContent = '';
}
}
if ($currentContent !== '') {
$tmp = SCRIPT_DIR . 'tmp' . DIRECTORY_SEPARATOR . $fileCount++;
file_put_contents($tmp, $currentContent);
$splitFiles[] = $tmp;
}
}
fclose($fHandle);
return $splitFiles;
}
function _chooseGraph()
{
$command = 'isql VERBOSE=OFF "EXEC=SELECT ID_TO_IRI(REC_GRAPH_IID) AS GRAPH FROM DB.DBA.RDF_EXPLICITLY_CREATED_GRAPH"';
$output = shell_exec($command);
$outputLines = explode("\n", $output);
$startReached = false;
$graphs = array();
foreach ($outputLines as $line) {
$trimmedLine = trim($line);
if ($trimmedLine === '') {
continue;
}
if (strpos($trimmedLine, '______________________________') !== false) {
$startReached = true;
continue;
}
if ($startReached) {
$graphs[] = $line;
}
}
echo "Choose a graph:\n";
foreach ($graphs as $i=>$g) {
echo " ($i) $g" . PHP_EOL;
}
echo "Just type in the number: ";
$input = intval(trim(fgets(STDIN)));
if (isset($graphs[$input])) {
return $graphs[$input];
}
return false;
}
function _importFile($file, $graph)
{
$command = "isql 1111 dba dba \"EXEC=TTLP(file_to_string_output('$file'), '', '$graph', 255)\" 2>&1 1> /dev/null";
$output = shell_exec($command);
if (null !== $output) {
var_dump($output);return;
return false;
}
return true;
}
================================================
FILE: application/scripts/runExtensionTests.sh
================================================
#!/bin/bash
extensionName="$1"
if [ "$extensionName" == "" ]
then
echo "No extension name provided"
exit 1;
fi
extensionDir="./extensions/$extensionName"
if [ ! -e "$extensionDir" ]
then
echo "The extension $extensionDir does not exist ..."
exit 1
fi
phpunit --bootstrap application/tests/Bootstrap.php $extensionDir
================================================
FILE: application/scripts/travis/README.md
================================================
- `install-services.sh` to handle the install of additional services
## SPARQL services
This file and scripts are taken form the SemanticMediaWiki repo and only selected files where copied for running tests with virtuoso.
It is taken as of commit 721a63d3a73400300f73e0a088196a6ed0fe5afd from https://github.com/SemanticMediaWiki/SemanticMediaWiki.
The unsupported services are marked with *Enabled* "No".
1 When running integration tests with [Jena Fuseki][fuseki] it is suggested that the `in-memory` option is used to avoid potential loss of production data during test execution.
2 Currently, Travis-CI doesn't support `4Store` (1.1.4-2) as service but the following configuration has been sucessfully tested with the available test suite. ([issue #110](https://github.com/garlik/4store/issues/110) )
[fuseki]: https://jena.apache.org/
[virtuoso]: https://github.com/openlink/virtuoso-opensource
[4store]: https://github.com/garlik/4store
================================================
FILE: application/scripts/travis/install-extensions.sh
================================================
#!/bin/bash
echo $TRAVIS_PHP_VERSION
# skip hhvm
if [[ $TRAVIS_PHP_VERSION = "hhv"* ]]; then
exit 0
fi
# get build dependencies
sudo apt-get install -y unixodbc-dev
PHPVERSION=$( php -v | head -n1 | sed "s|^PHP \([0-9][0-9\.]*\).*$|\1|" | tr -d '\n' )
ls ~/.phpenv/versions/
echo "PHPVERSION: " $PHPVERSION
echo "LOADED CONFIG: " `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
# get php sources
wget https://github.com/php/php-src/archive/php-$PHPVERSION.tar.gz
ls
tar -xzf php-$PHPVERSION.tar.gz
# build odbc extension
cd php-src-php-$PHPVERSION/ext/odbc/
phpize
# use fix from https://github.com/docker-library/php/issues/103
sed -ri 's@^ *test +"\$PHP_.*" *= *"no" *&& *PHP_.*=yes *$@#&@g' configure
./configure --with-unixODBC=shared,/usr
make
make install
# enable odbc
echo "extension=odbc.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
# build pdo_odbc
cd ../pdo_odbc/
phpize
./configure --with-pdo-odbc=unixODBC,/usr
make
make install
#enable pdo_odbc
echo "extension=pdo_odbc.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`
php -m
================================================
FILE: application/scripts/travis/install-services.sh
================================================
#!/bin/bash
set -ex
BASE_PATH=$(pwd)
E_UNREACHABLE=86
# skip hhvm
if [[ $TRAVIS_PHP_VERSION = "hhv"* ]]; then
exit 0
fi
if [ "$FOURSTORE" != "" ] || [ "$VIRTUOSO" != "" ] || [ "$SESAME" != "" ] || [[ "$FUSEKI" == "2."* ]]
then
sudo apt-get update -qq
fi
# Version 1.1.0 is available and testable on Travis/SMW
if [ "$FUSEKI" != "" ]
then
# Archive
# http://archive.apache.org/dist/jena/binaries/jena-fuseki-$FUSEKI-distribution.tar.gz
# http://www.eu.apache.org/dist/jena/binaries/jena-fuseki-$FUSEKI-distribution.tar.gz
# Avoid ERROR 503: Service Unavailable
# wget http://archive.apache.org/dist/jena/binaries/jena-fuseki-$FUSEKI-distribution.tar.gz
if [[ "$FUSEKI" == "2."* ]]
then
# Fuseki requires Java8 for Fuseki2 v2.3.0 onwards
sudo apt-get install oracle-java8-installer
export JAVA_HOME="/usr/lib/jvm/java-8-oracle";
export PATH="$PATH:/usr/lib/jvm/java-8-oracle/bin";
export java_path="/usr/lib/jvm/java-8-oracle/jre/bin/java";
wget https://github.com/mwjames/travis-support/raw/master/fuseki/$FUSEKI/apache-jena-fuseki-$FUSEKI.tar.gz
# option z caused "gzip: stdin: not in gzip format"
tar -xf apache-jena-fuseki-$FUSEKI.tar.gz
mv apache-jena-fuseki-$FUSEKI fuseki
else
wget https://github.com/mwjames/travis-support/raw/master/fuseki/$FUSEKI/jena-fuseki-$FUSEKI-distribution.tar.gz
tar -zxf jena-fuseki-$FUSEKI-distribution.tar.gz
mv jena-fuseki-$FUSEKI fuseki
fi
cd fuseki
## Start fuseki in-memory as background
bash fuseki-server --update --mem /db &>/dev/null &
fi
if [ "$SESAME" != "" ]
then
TOMCAT_VERSION=tomcat6
sudo java -version
sudo apt-get install $TOMCAT_VERSION
CATALINA_BASE=/var/lib/$TOMCAT_VERSION
CATALINA_HOME=/usr/share/$TOMCAT_VERSION
sudo chown $USER -R $CATALINA_BASE/
sudo chmod g+rw -R $CATALINA_BASE/
sudo mkdir -p $CATALINA_HOME/.aduna
sudo chown -R $TOMCAT_VERSION:$TOMCAT_VERSION $CATALINA_HOME
# One method to get the war files
# wget http://search.maven.org/remotecontent?filepath=org/openrdf/sesame/sesame-http-server/$SESAME/sesame-http-server-$SESAME.war -O openrdf-sesame.war
# wget http://search.maven.org/remotecontent?filepath=org/openrdf/sesame/sesame-http-workbench/$SESAME/sesame-http-workbench-$SESAME.war -O openrdf-workbench.war
# cp *.war /var/lib/tomcat6/webapps/
# http://sourceforge.net/projects/sesame/
# Unreliable sourceforge.net download
# wget http://downloads.sourceforge.net/project/sesame/Sesame%202/$SESAME/openrdf-sesame-$SESAME-sdk.zip
wget https://github.com/mwjames/travis-support/raw/master/sesame/$SESAME/openrdf-sesame-$SESAME-sdk.zip
# tar caused a lone zero block, using zip instead
unzip -q openrdf-sesame-$SESAME-sdk.zip
cp openrdf-sesame-$SESAME/war/*.war $CATALINA_BASE/webapps/
sudo service $TOMCAT_VERSION restart
ps -ef | grep tomcat
sleep 5
if curl --output /dev/null --silent --head --fail "http://localhost:8080/openrdf-sesame"
#if curl --output /dev/null --silent --head --fail "http://localhost:8080/openrdf-sesame/home/overview.view"
then
echo "openrdf-sesame service url is reachable"
else
echo "openrdf-sesame service url is not reachable"
sudo cat $CATALINA_BASE/logs/*.log &
sudo cat $CATALINA_BASE/logs/catalina.out &
exit $E_UNREACHABLE
fi
./openrdf-sesame-$SESAME/bin/console.sh < $BASE_PATH/scripts/travis/openrdf-sesame-memory-repository.txt
fi
# Version 1.1.4-1 is available but has a problem
# https://github.com/garlik/4store/issues/110
# 4STORE can not be used as variable name therefore FOURSTORE
if [ "$FOURSTORE" != "" ]
then
sudo mkdir /var/lib/4store/
sudo mkdir /var/lib/4store/db
sudo chown $USER -R /var/lib/4store/
sudo chmod g+rw -R /var/lib/4store/
sudo apt-get install 4store=$FOURSTORE
## Disabling the firewall
sudo iptables -F
4s-backend-setup db
4s-backend db
## Output the current process table
ps auwwx | grep 4s-
## -D only used to check the status of the 4store instance
## 4s-httpd -D -p 8088 db
4s-httpd -p 8088 db
fi
# We build all Virtuoso version from scratch
if [[ "$VIRTUOSO" != "" ]]
then
sudo apt-get install libssl-dev -q
sudo apt-get install autoconf automake bison flex gawk gperf libtool -q
if [[ -f virtuoso-opensource/$VIRTUOSO/binsrc/virtuoso/virtuoso-t ]]
then
echo "use cached virtuoso-opensource"
cd virtuoso-opensource/$VIRTUOSO
else
#git clone git://github.com/openlink/virtuoso-opensource.git
#cd virtuoso-opensource
#git pull origin stable/7
wget --no-check-certificate -q https://github.com/openlink/virtuoso-opensource/archive/v$VIRTUOSO.zip -O virtuoso-opensource.zip
unzip -q virtuoso-opensource.zip
rm -r virtuoso-opensource/$VIRTUOSO || true
mv virtuoso-opensource-$VIRTUOSO virtuoso-opensource/$VIRTUOSO
cd virtuoso-opensource/$VIRTUOSO
./autogen.sh
# --disable-all-vads: This parameter disables building all the VAD packages (tutorials, demos, etc.).
# --with-readline: This parameter is used so that the system Readline library is used
# --program-transform-name: Both Virtuoso and unixODBC install a program named isql. Use this parameter to rename virtuosos program to isql-v
./configure --program-transform-name="s/isql/isql-v/" --with-readline --disable-all-vads |& tee #configure.log
# Only output error and warnings
make > /dev/null
fi
# Build tree to start the automated test suite
# make check
sudo make install
## For Virtuoso
#export PATH=$PATH:/usr/local/virtuoso-opensource/bin
sudo /usr/local/virtuoso-opensource/bin/virtuoso-t -f -c /usr/local/virtuoso-opensource/var/lib/virtuoso/db/virtuoso.ini &
#sudo /usr/local/virtuoso-opensource/bin/virtuoso-t -f &
sleep 15
sudo /usr/local/virtuoso-opensource/bin/isql-v 1111 dba dba $BASE_PATH/application/scripts/travis/virtuoso-sparql-permission.sql
# configure datasource name for ODBC connection
echo "[VOS_TEST]" | sudo tee -a /etc/odbc.ini > /dev/null
echo "Driver=/usr/local/virtuoso-opensource/lib/virtodbc.so" | sudo tee -a /etc/odbc.ini > /dev/null
echo "Description=Virtuoso OpenSource Edition" | sudo tee -a /etc/odbc.ini > /dev/null
echo "Address=localhost:1111" | sudo tee -a /etc/odbc.ini > /dev/null
fi
#@see http://wiki.blazegraph.com/wiki/index.php/NanoSparqlServer
if [ "$BLAZEGRAPH" != "" ]
then
#sudo apt-get install tomcat6
#sudo chown $USER -R /var/lib/tomcat6/
#sudo chmod g+rw -R /var/lib/tomcat6/
#sudo mkdir -p /usr/share/tomcat6/.aduna
#sudo chown -R tomcat6:tomcat6 /usr/share/tomcat6
# http://sourceforge.net/projects/bigdata/
#wget http://downloads.sourceforge.net/project/bigdata/bigdata/$BLAZEGRAPH/bigdata.war
#cp bigdata.war /var/lib/tomcat6/webapps/
#export JAVA_OPTS="-server -Xmx2g -Dcom.bigdata.rdf.sail.webapp.ConfigParams.propertyFile="$BASE_PATH/scripts/travis/blazegraph-store.properties
#sudo service tomcat6 restart
#sleep 3
#Using the jar
# Unreliable sourceforge.net download
# wget http://downloads.sourceforge.net/project/bigdata/bigdata/$BLAZEGRAPH/bigdata-bundled.jar
wget https://github.com/mwjames/travis-support/raw/master/blazegraph/$BLAZEGRAPH/bigdata-bundled.jar
java -server -Xmx4g -Dbigdata.propertyFile=$BASE_PATH/scripts/travis/blazegraph-store.properties -jar bigdata-bundled.jar &>/dev/null &
sleep 5
if curl --output /dev/null --silent --head --fail "http://localhost:9999/bigdata"
then
echo "blazegraph service url is reachable"
else
echo "blazegraph service url is not reachable"
exit $E_UNREACHABLE
fi
fi
================================================
FILE: application/scripts/travis/virtuoso-sparql-permission.sql
================================================
GRANT EXECUTE ON DB.DBA.SPARQL_INSERT_DICT_CONTENT TO "SPARQL";
GRANT EXECUTE ON DB.DBA.SPARQL_DELETE_DICT_CONTENT TO "SPARQL";
GRANT EXECUTE ON SPARQL_DELETE_DICT_CONTENT to "SPARQL";
GRANT EXECUTE ON SPARQL_DELETE_DICT_CONTENT to SPARQL_UPDATE;
GRANT SPARQL_UPDATE to "SPARQL";
GRANT SPARQL_SPONGE to "SPARQL";
================================================
FILE: application/scripts/vad/README.txt
================================================
1. configure variables at top of prepare.sh script
2. running ./prepare.sh will checkout an OW into /tmp/ontowiki and run a virtuoso with the vad.ini config file (in /tmp/virtuoso)
3. open a new shell
3. type:
path/to/isql 9999 dba dba 'DB.PACK.VAD.isql'
================================================
FILE: application/scripts/vad/ow_vad_sticker_template.xml
================================================
]]>
http://blog.aksw.org/2010/aksw-presents-four-papers-at-iswc-in-shanghai-and-wins-best-paper-award/feed/OntoWiki 0.9.5 Available
http://blog.aksw.org/2010/ontowiki-095-available/
http://blog.aksw.org/2010/ontowiki-095-available/#commentsMon, 14 Jun 2010 14:55:47 +0000Sebastian TrampSoftware ReleasesOntoWikiOntoWikiReleasehttp://blog.aksw.org/2010/ontowiki-095-available/The AKSW research group is pleased to announce that OntoWiki 0.9.5 is now available for download.
OntoWiki is a web-application enabling the collaborative creation and (linked data) publication of RDF knowledge bases.
Support for Semantic Pingback, a protocol which enables OntoWiki to communicate named links from linked data resources or blog systems like WordPress.
Support for the publication of provenance information via Linked Data.
A new navigation module which support the configuration and usage of arbitrary navigation hierarchies (e.g. based on classes, SKOS elements, geospatial entities or FOAF groups).
A bookmarklet for collecting RDFa-based information into a specific OntoWiki knowledge base.
More editing widgets, e.g. for phone number and mailto: resources.
A new mapping module for the resource visualisation and filtering based on maps.
Attribute / Tag clouds based on selected RDF properties.
A GUI for complex SPARQL filter (contains, larger, smaller, between and bound)
A JSON/RPC server as an additional interface (e.g. for the command line client)
A plugin to create nice URIs based on the content of a new resource.
A detailed log of the over 200 enhancements and bug fixes of this release is available at our issue tracker.
Many thanks to the contributors of this OntoWiki release (in alphabetical order): Atanas Alexandrov, Christian Maier, Christoph Riess, Jonas Brekle, Marvin Frommhold, Michael Haschke, Michael Martin, Michael Niederstätter, Natanael Arndt, Norman Heino, Philipp Frischmuth and Tim Ermilov
best regards
Sebastian Tramp
]]>http://blog.aksw.org/2010/ontowiki-095-available/feed/owcli 0.3 released
http://blog.aksw.org/2010/owcli-03-released/
http://blog.aksw.org/2010/owcli-03-released/#commentsFri, 09 Apr 2010 12:49:10 +0000Sebastian TrampSoftware ReleasesOntoWikihttp://blog.aksw.org/2010/owcli-03-released/We’ve released the third version of our OntoWiki Command Line Interface (owcli). owcli is a php-based command line tool to administrate and manipulate OntoWiki Knowledge Bases. The release is a complete remake as an JSON/RPC client in order are save for future extensions at the OntoWiki RPC server base. owcli can be downloaded at the google code download page and is featured in detail at this wiki page.
]]>http://blog.aksw.org/2010/owcli-03-released/feed/Linked Opend Data Project of the Faculty of Mathematics and Computer Science at Leipzig University
http://blog.aksw.org/2010/linked-opend-data-project-of-the-faculty-of-mathematics-and-computer-science-at-leipzig-university/
http://blog.aksw.org/2010/linked-opend-data-project-of-the-faculty-of-mathematics-and-computer-science-at-leipzig-university/#commentsFri, 09 Apr 2010 11:35:53 +0000ThomasRiechertAnnouncementsProjectsOntoWikihttp://blog.aksw.org/2010/linked-opend-data-project-of-the-faculty-of-mathematics-and-computer-science-at-leipzig-university/From this summer term onwards the Faculty of Mathematics and Computer Science at Leipzig University provides structured information about academia such aslectures, tutors, rooms and timetables as Linked Open Data. The platform http://od.fmi.uni-leipzig.de, which is based on the OntoWiki framework, provides a vocabulary and an ontology. Apart from the possibility of the direct linking of resources in the semantic web, this platformn offers a SPARQL endpoint. The accessible information provides a basis for the integration into E-Learning platforms or personal knowledge management applications.
]]>http://blog.aksw.org/2010/linked-opend-data-project-of-the-faculty-of-mathematics-and-computer-science-at-leipzig-university/feed/AKSW Publications on this Year’s Leipzig Book Fair
http://blog.aksw.org/2010/aksw-publications-on-this-years-leipzig-book-fair/
http://blog.aksw.org/2010/aksw-publications-on-this-years-leipzig-book-fair/#commentsThu, 18 Mar 2010 11:45:06 +0000ThomasRiechertAnnouncementsProjectsOntoWikiEventsSoftWikihttp://blog.aksw.org/2010/aksw-publications-on-this-years-leipzig-book-fair/At this year’s book fair in Leipzig (18/03 - 21/03) two books resulting from current project work of the AKSW research group [1,2] are displayed within the scope of scientific publications from the University of Leipzig. One of the editors, Thomas Riechert, will be present on 19th March from 10 to 12 o’clock at booth G201/H200 (hall 3).
[1] Agiles Requirements Engineering für Softwareprojekte mit einer großen Anzahl verteilter Stakeholder. Sören Auer, Kim Lauenroth, Steffen Lohmann and Thomas Riechert (Eds.),
2009, Leipziger Informatik Verbund (LIV), http://softwiki.de/buch
[2] Catalogus Professorum Lipsiensis - Konzeption, technische Umsetzung und Anwendungen für Professorenkataloge im Semantic Web.
Ulf Morgenstern and Thomas Riechert (Eds.), 2010, Leipziger Informatik Verbund (LIV), http://catalogus-professorum.org/buch
]]>http://blog.aksw.org/2010/aksw-publications-on-this-years-leipzig-book-fair/feed/
================================================
FILE: application/tests/unit/phpunit.xml.dist
================================================
.../../../application../../../application/scripts../../../application/tests../../../application/shell.worker.client.php../../../application/shell.worker.php
================================================
FILE: application/views/templates/application/about.phtml
================================================
data as $name => $section): ?>
The resource requestedUrl; ?> you are trying to reach does not exist.
Do you want to create it?
Otherwise, try to urlBase; ?>">go back.
================================================
FILE: application/views/templates/error/500.phtml
================================================
500: Internal Server Error
Internal Server Error
We're sorry, but something went wrong (e.g. configuration).
Please inform your system administrator.
Details are logged and debug mode can be turned on.
instanceData[$this->instanceUri][$property['varName']] as $value): ?>
…OW_SHOW_MAX won't show
}
if($i==2){
//if there is more than one value, show the "show as list" link (looks like this is printed between the first and second value, but its hidden and shown as a context menu)
?>
================================================
FILE: application/views/templates/partials/table.phtml
================================================
*/
if ($this->has('tableClass')) {
echo '
' . PHP_EOL;
} else {
echo '
' . PHP_EOL;
}
if ($this->has('caption')) {
echo "
$this->caption
" . PHP_EOL;
}
if ($this->has('header')) {
echo '
' . PHP_EOL;
foreach ($this->header as $headerField) {
echo "
$headerField
" . PHP_EOL;
}
echo '
' . PHP_EOL;
}
// row counter for data cell Ids
$r = 0;
$oddClass = 'even';
foreach ($this->data as $row) {
// column counter for data cell Ids
$c = 0;
// swith odd/even class
$oddClass = ($oddClass == 'even') ? 'odd' : 'even';
// prepare classes of the tr element
$rowClassValue = '';
if ($this->has('rowClass')) {
$rowClassValue .= $this->rowClass;
}
if (!$this->has('noodds') || $this->noodds === false) {
$rowClassValue .= ' ' . $oddClass;
}
echo "
" . PHP_EOL;
foreach ($row as $field) {
// data cell Id (r3-c12)
$id = 'r' . $r . '-c' . $c ;
if ($this->has('itemClass')) {
echo '
';
} else {
echo '
';
}
// enhance data cell if value is an URI
// (and option is set)
if (
$this->has('querylink') &&
$this->querylink === true &&
Erfurt_URI::check($field)
) {
// the query which is sent to the query editor
$query = "SELECT ?predicate ?object" . PHP_EOL .
"WHERE {" . PHP_EOL .
" <$field> ?predicate ?object ." . PHP_EOL .
"}";
// the links href
$url = new OntoWiki_Url(
array(
'controller' => 'queries',
'action' => 'editor'
),
array(),
array('query')
);
// append query parameter (setParam not used intentional here)
// reason: failes with the query part
$url = $url . '?query=' . urlencode($query);
// output the link
echo '' . $this->escape($field) . '';
} else {
// output only the value
echo $this->escape($field);
}
echo '
namespacePrefixes as $prefix => $namespace): ?>
>
predicates as $graph => $predicatesForGraph): ?>
predicates[$graph]) > 0): /* has resource predicates from graph at all? */ ?>
1) || ($graph != $this->graphUri)): ?>
graphUri) ? $this->_('Imported from ') : '' ?>
graphs[$graph] ?>
$predicate): ?>
predicates[$graph][$uri] ?>
show list icon ?>
show list icon
$hasListLink = false;
if (count($this->values[$graph][$uri]) > 1) {
foreach ($this->values[$graph][$uri] as $entry) {
if ($entry['url']) {
$hasListLink = true;
}
}
}
?>
">
Show as List
editableFlags[$graph] == true) : ?>
Show as List
================================================
FILE: build/phpcs.xml
================================================
OntoWiki rule set for PHP_CodeSniffer
================================================
FILE: build.xml
================================================
================================================
FILE: composer.json
================================================
{
"name": "aksw/ontowiki",
"description": "Semantic data wiki as well as Linked Data publishing engine",
"type": "application",
"keywords": ["OntoWiki", "Linked Data", "Semantic Web", "RDF", "Triple Store"],
"license": "GPL-2.0",
"authors": [
{
"name": "Natanael Arndt",
"email": "arndtn@gmail.com"
},
{
"name": "AKSW",
"homepage": "http://aksw.org"
}
],
"require": {
"php": ">=5.4.0",
"mnsami/composer-custom-directory-installer": "1.1.*",
"aksw/erfurt": "1.8.*",
"bitworking/mimeparse": "2.1.*",
"zendframework/zendframework1": "1.*",
"aksw/rdfauthor": "dev-develop",
"composer/installers": ">=1.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.5.*",
"squizlabs/php_codesniffer": "dev-master"
},
"extra": {
"installer-paths": {
"./libraries/RDFauthor": ["aksw/rdfauthor"]
}
},
"autoload": {
"classmap": [
"extensions/",
"application/Bootstrap.php",
"application/classes/",
"application/controllers/"
]
},
"minimum-stability": "dev",
"prefer-stable": true
}
================================================
FILE: config.ini.dist
================================================
;;;;
;; OntoWiki user config file
;;
;; Settings here will overwrite values from application/config/default.ini
;;
;; @package application
;; @subpackage config
;; @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
;; @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
;;
[private]
;;;;
;; Database setup
;; In most cases you only need to change username, password
;; and database name (dbname).
;;;;
;; Backend type:
;; Possible values are zenddb (mysql), virtuoso, arc, comparer and sparql
;;
store.backend = virtuoso
;;;;
;; ZendDB / MySQL backend specific options
;;
store.zenddb.dbname = "ontowiki"
store.zenddb.username = "php"
store.zenddb.password = "php"
store.zenddb.dbtype = mysql
store.zenddb.host = localhost
;;;;
;; Virtuoso backend specific options
;;
store.virtuoso.dsn = VOS
store.virtuoso.username = "dba"
store.virtuoso.password = "dba"
;; affect the main search: searches <= 4 will be exact search (instead of bif:contains)
store.virtuoso.search_max_length_for_bifcontains = "4"
;store.virtuoso.use_persistent_connection = true
;;;;
;; ARC2 backend specific options
;;
store.arc.dbname = "ontowiki_arc2"
store.arc.username = "ow"
store.arc.password = "ow"
store.arc.host = "localhost"
store.arc.store = "ef"
;store.sparql.serviceUrl = "http://dbpedia.org/sparql";
;store.sparql.graphs[] = "http://dbpedia.org"
;;;;
;; Comparer backend specific options
;;
store.comparer.reference = virtuoso
store.comparer.candidate = zenddb
store.comparer.ignoredMethods[] = sparqlQuery
;;;;
;; Frontend language
;;
languages.locale = "en" ; en, de, ru, zh (Chinese)
;;;;
;; Set this identifier to a unique value if you want to run multiple OntoWiki
;; installations on one server
;;
;session.identifier = "abc123"
;;;;
;; Set some session cookie parameters
;session.lifetime = "3600"
;session.path = "/"
;session.domain = ""
;session.secure = 0
;session.httpOnly = 0
;;;;
;; Email configuration
;; You should set the host and localname for account recovery mails here
;; appropriate values are necessary to guarantee correct function
;;
mail.hostname = "hostname.tld"
mail.localname.recovery = "ontowiki-account-recovery"
;;;;
;; Proxy configuration
;; You can configure an optional proxy server for connections that OntoWiki internally opens.
;; This is for example useful in situations, where you want to access Linked Data and your OntoWiki sits
;; behind a firewall.
;;
;proxy.host = ""
;proxy.port = 8080
;proxy.username = ""
;proxy.password = ""
;; Virtual host configurations (optional, e.g. when OntoWiki is reachable via multiple domains)
;vhosts[] = "http://graph1.ontowiki.de"
;vhosts[] = "http://graph2.ontowiki.de"
;;;;
;; Uncomment this line to turn on the query and object cache (experimental)
;;
;cache.enable = true
;cache.query.enable = true
;; Options for cache frontend (experimental)
;cache.frontend.enable = true
;cache.frontend.lifetime = 0
;cache.frontend.logging = false
;cache.frontend.write_control = true
;cache.frontend.automatic_cleaning_factor = 10
;cache.frontend.ignore_user_abort = false
;cache.frontend.cache_id_prefix = 'OW_'
;; Cache backend options
;; Available: file | memcached | database | sqlite | apc
;; Recommended: memcached | file
;cache.backend.type = "file"
;; Options for file cache backend
;cache.backend.file.cache_dir = "./cache/"
;cache.backend.file.file_locking = NULL
;; Options for memcached cache backend
;cache.backend.memcached.compression = false
;cache.backend.memcached.compatibility = false
;; You can define several servers: copy block, below and increase number and configure properly
;cache.backend.memcached.servers.0.host = "localhost"
;cache.backend.memcached.servers.0.port = 11211
;cache.backend.memcached.servers.0.persistent = true
;cache.backend.memcached.servers.0.weight = 1
;cache.backend.memcached.servers.0.timeout = 5
;cache.backend.memcached.servers.0.retry_interval = 15
;cache.backend.memcached.servers.0.status = 15
;; Options for sqlite cache backend
cache.backend.sqlite.cache_db_complete_path = "/tmp/ow_cache.sqlite"
;cache.backend.sqlite.automatic_vacuum_factor = 10
;; Options for Gearman/worker (experimental)
;worker.enable = true
;; Option for specifying the RSS/Atom feed loaded in the OntoWiki index actions "News" module
;; set to "false" to completely disable the feed
;news.feedUrl = "http://blog.aksw.org/feed/?cat=5&client={{version.label}}&version={{version.number}}&suffix={{version.suffix}}"
;;;;
;; uncomment this line if you need more information
;;
;debug = true
================================================
FILE: debian/Makefile/Makefile
================================================
default:
prepare:
rm -rf ../../build*
rm -f ../../Makefile
rm -f ../../web.config
rm -rf ../../libraries/Erfurt
rm -rf ../../libraries/RDFauthor
rm -f ../../extensions/themes/silverblue/scripts/libraries/jquery.js
rm -f ../../extensions/exconf/pclzip.lib.php
rm -rf ../../extensions/markdown/parser
rm -f ../../extensions/queries/resources/codemirror/LICENSE
clean:
rm -rf ../*.log
rm -rf ../ontowiki-common
rm -rf ../ontowiki-mysql
rm -rf ../ontowiki-virtuoso
rm -rf ../files
rm -rf ../*.substvars
package:
================================================
FILE: debian/changelog
================================================
ontowiki (0.9.11) lod2; urgency=low
* Improve model selection in linkeddataserver extension
* Extend cache clear script by support for query and translation cache
* Fix #60: Add script to clear cache via shell
* fix #201 - removed css classes for modal and set z-index of applicationbar to 999
* Fix 271. Fix Output Format of queries editor
* fix #201 - fixed z-index for modal-wrapper-propertyselector
* Merge pull request #268 from hknochi/feature/fix-extension-enabler
* Merge pull request #269 from hknochi/feature/fix-pagination
* fix issue #167 - invalidate extensionCache to distribute requested changes
* fix issue #261 - added limit-parameter to url
* improve cron job
* Add list-events target to Makefile
* remove log in about screen
* avoid broken feed URLs on version / names with spaces
* use configure name instead of hardcoded one
* fixed issue #201 - added css rules for modal-wrapper
* fixed issue #201 - added css rules for simplemodal-container and -overlay
* Fix build to ignore worker shell scripts
* Reorganize shell scripts to avoid build failure
* Cleanup mail extension job class by removing obsolete members
* Added console client and an example extension for testing Erfurts worker
* Add support for Erfurts background jobs
* add min-height to in resource view
* Add hidden save and cancle buttons in listmode
* Reorganize some code in support.js
* Fix editProperty to work in extended mode (+)
* Allow configuration of session cookie parameters, such as session lifetime
* Fix #259. Write alle defined prefixes to RDFa output.
* Fix warning, when site redirect takes place. Fix #260.
* fix wrong server class includes (closes #256)
* initial version of SelectorModule
* Fix model creation if no title is specified
* move inner window modules outside of master form
* Add “View as Resource” entry to model menu. Fix #152
* fix wrong encoded query parameter
* add even/odd classes for row and noodds parameter
* use new querylink feature of table partial
* remake table partial, add query link enhancement
* Fix #152. Move menu creation to Menu_Registry. [34m(6 months ago by Natanael Arndt)[m
* add xdebug link
* Remove unused action service/entities
-- Sebastian Tramp Fri, 31 Jan 2014 15:46:49 +0100
ontowiki (0.9.10-1) lod2; urgency=low
* new model creation / add data procedure
* fixes in query editor
* performance issues in title helper
* unify CommentModule and LastcommentsModule, increase limit and set ordering
* +100 other commits
* depends on Erfurt 1.6
* depends on RDFauthor 0.9.6
-- Sebastian Tramp Wed, 10 Jul 2013 14:22:14 +0200
ontowiki (0.9.8-3) lod2; urgency=low
* fix cors header
* add doap:wiki to the weblink list (2 weeks ago by Sebastian Tramp)
* add head action to return the request header for given uri
* fix extensions setting page (toggleswitch) #179
* Fixing Sort functionality of the Navigation Box extension re-enabling the Sort Menue
* prevent open paranthesis bug while using the limit buttons (100 / all)
* Fix #172 - rewrite rules in .htaccess
* use getReadableGraphsUsingResource method on Store
* cleanup togglebutton changes
* fix toggle button for new jquery version (#167)
* depends on Erfurt 1.5
* depends on RDFauthor 0.9.5
-- Sebastian Tramp Wed, 30 Jan 2013 13:55:56 +0100
ontowiki (0.9.7-2) lod2; urgency=low
* GUI niceups
* lots of fixes
* https://github.com/AKSW/OntoWiki/issues?milestone=1&page=1&state=closed
* RDFauthor is now a separate package
* Add support for additonal vhosts
* increment RDFauthor dependency
* allow usage of virtuosos bd.ini if present
* add gnome desktop file
-- Sebastian Tramp Fri, 16 Nov 2012 08:30:27 -0800
ontowiki (0.9.6-21) lod2; urgency=low
* fix RDFauthor integration
* forward RDFauthor to b780680
* forward OntoWiki to 04b33fd
-- Sebastian Tramp Mon, 27 Feb 2012 10:42:49 +0100
ontowiki (0.9.6-20) lod2; urgency=low
* forward ontowiki to 4bcd852
* forward RDFauthor to 3072d23
* fix non-writable extension directory
-- Sebastian Tramp Fri, 24 Feb 2012 01:50:21 +0100
ontowiki (0.9.6-19) lod2; urgency=low
* merged new develop branches into debian package
-- Sebastian Tramp Wed, 25 Jan 2012 10:03:59 +0100
ontowiki (0.9.6-18) lod2; urgency=low
* Adds support for case-insensitive URI matching and trailing slashes tolerance.
* Add text/turtle to type mappings.
* remove patternmanager, tagging, csvimport, site and map extensions
* improve error messages on bootstrap
* build from moved github sources
-- Sebastian Tramp Tue, 04 Oct 2011 14:42:39 +0200
ontowiki (0.9.6-17) lod2; urgency=low
* removed detailed dependency information for more compatibility
* fixed CKAN link
-- Sebastian Tramp Fri, 02 Sep 2011 20:47:47 +0200
ontowiki (0.9.6-16) lod2; urgency=low
* fix: RDFauthor integration
-- Sebastian Tramp Thu, 01 Sep 2011 10:01:16 +0200
ontowiki (0.9.6-15) lod2; urgency=low
* feature: ckan registration for non localhost models
* fix: depends-on-essential-package-without-using-version (sed)
* fix: AllowDirs now for new erfurt position
* hack: virtuoso's dba acount used (this should be changed soon!)
* new dependency: libphp-pclzip for extension configuration
* new dependency: tinymce in RDFauthor
-- Sebastian Tramp Wed, 22 Jun 2011 05:45:00 +0200
ontowiki (0.9.6-14) lod2; urgency=low
* correct pwgen dependency
-- Sebastian Tramp Mon, 20 Jun 2011 10:58:27 +0200
ontowiki (0.9.6-13) lod2; urgency=low
* now with liberfurt-php dependency
-- Sebastian Tramp Thu, 09 Jun 2011 12:35:20 +0200
ontowiki (0.9.6-12) lod2; urgency=low
* virtuoso autoexec.isql now on correct place?
-- Sebastian Tramp Thu, 09 Jun 2011 12:35:20 +0200
ontowiki (0.9.6-11) lod2; urgency=low
* configuration directory split
* virtuoso autoexec.isql test
-- Sebastian Tramp Thu, 09 Jun 2011 08:35:20 +0200
ontowiki (0.9.6-10) lod2; urgency=low
* correct Depends, Replaces, Provides and Breaks tags
-- Sebastian Tramp Thu, 09 Jun 2011 08:00:31 +0200
ontowiki (0.9.6-9) lod2; urgency=low
* split package structure into virtuoso, mysql and common (sub-)packages
-- Sebastian Tramp Wed, 08 Jun 2011 17:01:51 +0200
ontowiki (0.9.6-8) lod2; urgency=low
* hopefully fixes install problems
-- Sebastian Tramp Wed, 08 Jun 2011 17:01:21 +0200
ontowiki (0.9.6-7) lod2; urgency=low
* docu addons
* depends on libmarkdown-php now
* security fix: file permissions
* license fix for codemirror
-- Sebastian Tramp Thu, 24 Mar 2011 15:48:57 +0100
ontowiki (0.9.6-6) lod2; urgency=low
* jquery-ui dependency deleted
-- Sebastian Tramp Thu, 24 Mar 2011 15:18:59 +0100
ontowiki (0.9.6-5) lod2; urgency=low
* (manual) database creation
* depends on jquery-ui now
-- Sebastian Tramp Thu, 24 Mar 2011 08:48:17 +0100
ontowiki (0.9.6-4) lod2; urgency=low
* a2enmod env
* depends on zend framework
* logs under /var/log/ontowiki
-- Sebastian Tramp Wed, 23 Mar 2011 16:00:43 +0100
ontowiki (0.9.6-3) lod2; urgency=low
* fix: a2enmod rewrite in postinst
-- Sebastian Tramp Tue, 22 Mar 2011 16:33:32 +0100
ontowiki (0.9.6-2) lod2; urgency=low
* better postinst handling
-- Sebastian Tramp Tue, 22 Mar 2011 13:28:42 +0100
ontowiki (0.9.6-1) lod2; urgency=low
* Initial debian release
-- Sebastian Tramp Wed, 02 Feb 2011 00:10:38 +0100
================================================
FILE: debian/compat
================================================
7
================================================
FILE: debian/conf/apache2/apache.conf
================================================
# OntoWiki Apache Configuration
# needed for following the config.ini
Options +FollowSymLinks
# Give all right the the htaccess
AllowOverride All
Alias /ontowiki /usr/share/ontowiki
================================================
FILE: debian/conf/gnome/ontowiki.desktop
================================================
[Desktop Entry]
Name=OntoWiki
Comment=A Semantic Data Wiki
Exec=gnome-www-browser http://localhost/ontowiki
Terminal=false
Type=Application
Icon=/usr/share/ontowiki/application/favicon.png
Categories=Utility;Application
StartupNotify=false
================================================
FILE: debian/conf/mysql/config.ini
================================================
;;
; OntoWiki user config file
;
; Settings here will overwrite values
; from default.ini.
;
; @package application
; @subpackage config
; @copyright Copyright (c) 2010, {@link http://aksw.org AKSW}
; @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
;;
[private]
;;
; Database setup
; In most cases you only need to change username, password
; and database name (dbname).
store.backend = zenddb ; zenddb, virtuoso, arc, comparer
store.zenddb.dbname = "ontowiki_deb"
store.zenddb.username = "ontowiki_deb"
store.zenddb.password = "usepwgenhere"
store.zenddb.dbtype = mysql ; mysql
;store.zenddb.host = localhost ; default is localhost
;store.virtuoso.dsn = vos505
;store.virtuoso.username = "dba"
;store.virtuoso.password = "dba"
;store.virtuoso.use_persistent_connection = true
;store.arc.dbname = "ontowiki_arc2"
;store.arc.username = "ow"
;store.arc.password = "ow"
;store.arc.host = "localhost"
;store.arc.store = "ef"
;store.comparer.reference = virtuoso
;store.comparer.candidate = zenddb
;store.comparer.ignoredMethods[] = sparqlQuery
;;
; Frontend language
;;
languages.locale = "en" ; en, de, ru, zh (Chinese)
;;
; Set this identifier to a unique value if you want to run multiple OntoWiki
; installations on one server
;;
;session.identifier = "abc123"
;;
; Email configuration
; You should set the host and localname for account recovery mails here
; appropriate values are necessary to guarantee correct function
;;
mail.hostname = "hostname.tld"
mail.localname.recovery = "ontowiki-account-recovery"
;;
; Proxy configuration
; You can configure an optional proxy server for connections that OntoWiki internally opens.
; This is for example useful in situations, where you want to access Linked Data and your OntoWiki sits
; behind a firewall.
;;
;proxy.host = ""
;proxy.port = 8080
;proxy.username = ""
;proxy.password = ""
================================================
FILE: debian/conf/virtuoso/config.ini
================================================
;;
; OntoWiki user config file
;
; Settings here will overwrite values
; from default.ini.
;
; @package application
; @subpackage config
; @copyright Copyright (c) 2010, {@link http://aksw.org AKSW}
; @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
;;
[private]
;;
; Database setup
; In most cases you only need to change username, password
; and database name (dbname).
store.backend = virtuoso ; zenddb, virtuoso, arc, comparer
; since openlink can't help here at the moment, we use dba/dba
store.virtuoso.dsn = "%%DSN%%"
store.virtuoso.username = "%%USERNAME%%"
store.virtuoso.password = "%%PASSWORD%%"
;store.virtuoso.use_persistent_connection = true
;;
; Frontend language
;;
languages.locale = "en" ; en, de, ru, zh (Chinese)
;;
; Set this identifier to a unique value if you want to run multiple OntoWiki
; installations on one server
;;
;session.identifier = "abc123"
;;
; Email configuration
; You should set the host and localname for account recovery mails here
; appropriate values are necessary to guarantee correct function
;;
mail.hostname = "hostname.tld"
mail.localname.recovery = "ontowiki-account-recovery"
;;
; Proxy configuration
; You can configure an optional proxy server for connections that OntoWiki internally opens.
; This is for example useful in situations, where you want to access Linked Data and your OntoWiki sits
; behind a firewall.
;;
;proxy.host = ""
;proxy.port = 8080
;proxy.username = ""
;proxy.password = ""
================================================
FILE: debian/control
================================================
Source: ontowiki
Section: web
Priority: extra
Maintainer: Sebastian Tramp
Build-Depends: debhelper (>= 7.0.50~)
Standards-Version: 3.9.3
Homepage: http://ontowiki.net
Vcs-Git: git://github.com/AKSW/OntoWiki.git
Vcs-Browser: https://github.com/AKSW/OntoWiki
Package: ontowiki-virtuoso
Architecture: all
Depends: ontowiki-common (>= 0.9.11), virtuoso-opensource-6.1 (>= 6.1.6), php5-odbc, ${misc:Depends}
Provides: ontowiki
Conflicts: ontowiki, ontowiki-mysql
Replaces: ontowiki (<< 0.9.6-10)
Breaks: ontowiki (<< 0.9.6-10)
Description: Semantic Data Wiki enabling the publication of RDF data
OntoWiki is a tool providing support for agile, distributed knowledge
engineering scenarios. OntoWiki facilitates the visual presentation of
a knowledge base as an information map, with different views on instance data.
.
It enables intuitive authoring of semantic content. It fosters social
collaboration aspects by keeping track of changes, allowing to comment and
discuss every single part of a knowledge base.
.
Other remarkable features are:
* OntoWiki is a Linked Data Server for you data as well as a Linked Data
client to fetch additional data from the web.
* OntoWiki is a Semantic Pingback Client in order to receive and send
back-linking request as known from the blogosphere.
* OntoWiki is backend independent, which means you can save your data in a
MySQL database as well as in a Virtuoso Triple Store.
* OntoWiki is easily extendible by you, since it features a sophisticated
Extension System.
.
This package will install a virtuoso-backended OntoWiki instance.
.
OntoWiki is part of the LOD2 Technology Stack.
Package: ontowiki-mysql
Architecture: all
Depends: ontowiki-common (>= 0.9.11), mysql-server, php5-mysql | php5-mysqli, ${misc:Depends}
Provides: ontowiki
Conflicts: ontowiki, ontowiki-virtuoso
Replaces: ontowiki (<< 0.9.6-10)
Breaks: ontowiki (<< 0.9.6-10)
Description: Semantic Data Wiki enabling the publication of RDF data
OntoWiki is a tool providing support for agile, distributed knowledge
engineering scenarios. OntoWiki facilitates the visual presentation of
a knowledge base as an information map, with different views on instance data.
.
It enables intuitive authoring of semantic content. It fosters social
collaboration aspects by keeping track of changes, allowing to comment and
discuss every single part of a knowledge base.
.
Other remarkable features are:
* OntoWiki is a Linked Data Server for you data as well as a Linked Data
client to fetch additional data from the web.
* OntoWiki is a Semantic Pingback Client in order to receive and send
back-linking request as known from the blogosphere.
* OntoWiki is backend independent, which means you can save your data in a
MySQL database as well as in a Virtuoso Triple Store.
* OntoWiki is easily extendible by you, since it features a sophisticated
Extension System.
.
This package will install a mysql-backended OntoWiki instance.
.
OntoWiki is part of the LOD2 Technology Stack.
Package: ontowiki-common
Architecture: all
Depends: liberfurt-php (>= 1.7), libjs-rdfauthor (>= 0.9.7), php5-curl, libmarkdown-php, libphp-pclzip, libjs-jquery (>= 1.7.1), tinymce, ${misc:Depends}
Suggests: owcli
Description: Application sources for all ontowiki packages
OntoWiki is a tool providing support for agile, distributed knowledge
engineering scenarios. OntoWiki facilitates the visual presentation of
a knowledge base as an information map, with different views on instance data.
.
This is the common data package of OntoWiki and part of the LOD2 Technology
Stack.
================================================
FILE: debian/copyright
================================================
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: Erfurt
Source: https://github.com/AKSW/Erfurt
Files: *
Copyright:
2013 Christian Würker
2013 Christoph Rieß
2013 Daniel Gerber
2013 Jonas Brekle
2013 Konrad Abicht
2013 Michael Haschke
2013 Michael Martin
2013 Natanael Arndt
2013 Norman Heino
2013 Philipp Frischmuth
2013 Rolland Brunec
2013 Sebastian Tramp
2013 Tim Ermilov
License: GPL-2+
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
.
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more
details.
.
You should have received a copy of the GNU General Public
License along with this package; if not, write to the Free
Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301 USA
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.
Files: extensions/queries/resources/codemirror/*
Copyright: 2013 Marijn Haverbeke
License: MIT2
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Files: debian/*
Copyright: 2013 Sebastian Tramp
License: GPL-2+
This program is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later
version.
.
This program is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the GNU General Public License for more
details.
.
You should have received a copy of the GNU General Public
License along with this package; if not, write to the Free
Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301 USA
.
On Debian systems, the full text of the GNU General Public
License version 2 can be found in the file
`/usr/share/common-licenses/GPL-2'.
================================================
FILE: debian/ontowiki-common.dirs
================================================
var/cache/ontowiki
var/log/ontowiki
================================================
FILE: debian/ontowiki-common.install
================================================
index.php usr/share/ontowiki
.htaccess usr/share/ontowiki
application/Bootstrap.php usr/share/ontowiki/application
application/classes usr/share/ontowiki/application
application/config usr/share/ontowiki/application
application/controllers usr/share/ontowiki/application
application/views usr/share/ontowiki/application
application/favicon.png usr/share/ontowiki/application
application/favicon.ico usr/share/ontowiki/application
extensions usr/share/ontowiki
libraries/ARC2 usr/share/ontowiki/libraries/
libraries/Mimeparse.php usr/share/ontowiki/libraries/
================================================
FILE: debian/ontowiki-common.links
================================================
/usr/share/php/libzend-framework-php/Zend /usr/share/ontowiki/libraries/Zend
/usr/share/php/liberfurt-php /usr/share/ontowiki/libraries/Erfurt
/usr/share/libjs-rdfauthor /usr/share/ontowiki/libraries/RDFauthor
/usr/share/php/markdown.php /usr/share/ontowiki/extensions/markdown/parser/markdown.php
/usr/share/javascript/jquery/jquery.min.js /usr/share/ontowiki/extensions/themes/silverblue/scripts/libraries/jquery.js
/usr/share/php/libphp-pclzip/pclzip.lib.php /usr/share/ontowiki/extensions/exconf/pclzip.lib.php
/var/log/ontowiki /usr/share/ontowiki/logs
/var/cache/ontowiki /usr/share/ontowiki/cache
================================================
FILE: debian/ontowiki-common.postinst
================================================
#!/bin/sh -e
# postinst script for ontowiki
#
# see: dh_installdeb(1)
echo "---- starting postinst $@"
chown www-data:www-data /usr/share/ontowiki/extensions
chown www-data:www-data /var/log/ontowiki
chown www-data:www-data /var/cache/ontowiki
chmod 770 /usr/share/ontowiki/extensions
chmod 770 /var/log/ontowiki
chmod 770 /var/cache/ontowiki
# enable the rewrite base
sed 's/#RewriteBase/RewriteBase/' -i /usr/share/ontowiki/.htaccess
#DEBHELPER#
echo "---- ending postinst $@"
================================================
FILE: debian/ontowiki-mysql.install
================================================
debian/conf/apache2/* etc/ontowiki
debian/conf/mysql/* etc/ontowiki
debian/sql/* usr/share/dbconfig-common/data/ontowiki/
debian/conf/gnome/* usr/share/applications
================================================
FILE: debian/ontowiki-mysql.links
================================================
/etc/ontowiki/config.ini /usr/share/ontowiki/config.ini
/etc/ontowiki/apache.conf /etc/apache2/conf.d/ontowiki
================================================
FILE: debian/ontowiki-mysql.postinst
================================================
#!/bin/sh -e
# postinst script for ontowiki
#
# see: dh_installdeb(1)
echo "---- starting postinst $@"
mysql_run="mysql --defaults-extra-file=/etc/mysql/debian.cnf"
ow_user="ontowiki_deb"
ow_db="$ow_user"
#ow_pass=`pwgen -1`
ow_pass="usepwgenhere"
#service mysql start
echo "create ontowiki user"
echo "CREATE USER '$ow_user'@'localhost' IDENTIFIED BY '$ow_pass';" | $mysql_run || echo "user $ow_user already exist"
echo "grant usage for ontowiki user"
echo "GRANT USAGE ON * . * TO '$ow_user'@'localhost' IDENTIFIED BY '$ow_pass' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;" | $mysql_run
echo "create database"
echo "CREATE DATABASE IF NOT EXISTS $ow_db ;" | $mysql_run
echo "grant privileges to ontowiki user"
echo "GRANT ALL PRIVILEGES ON $ow_db . * TO '$ow_user'@'localhost';" | $mysql_run
echo "flush privileges"
echo "FLUSH PRIVILEGES ;" | $mysql_run
### APACHE CONFIG
chown www-data:www-data /etc/ontowiki/config.ini
chmod 600 /etc/ontowiki/config.ini
a2enmod rewrite
a2enmod env
service apache2 restart
#DEBHELPER#
echo "---- ending postinst $@"
================================================
FILE: debian/ontowiki-mysql.prerm
================================================
#!/bin/sh -e
# prerm script for ontowiki
#
# see: dh_installdeb(1)
echo "---- starting prerm $@"
rm -f $APACHECONF_TARGET
service apache2 restart
#DEBHELPER#
echo "---- ending prerm $@"
================================================
FILE: debian/ontowiki-virtuoso.install
================================================
debian/conf/apache2/* etc/ontowiki
debian/conf/virtuoso/* etc/ontowiki
debian/sql/* usr/share/dbconfig-common/data/ontowiki/
debian/conf/gnome/* usr/share/applications
================================================
FILE: debian/ontowiki-virtuoso.links
================================================
/etc/ontowiki/config.ini /usr/share/ontowiki/config.ini
/etc/ontowiki/apache.conf /etc/apache2/conf.d/ontowiki
================================================
FILE: debian/ontowiki-virtuoso.postinst
================================================
#!/bin/sh -e
# postinst script for ontowiki-virtuoso
#
# see: dh_installdeb(1)
echo "---- starting postinst $@"
virtetc="/etc/virtuoso-opensource-6.1/"
virtuosoini="$virtetc/virtuoso.ini"
virtbdini="$virtetc/bd.ini"
odbcini="/etc/odbc.ini"
owini="/etc/ontowiki/config.ini"
dsn="OWVIRT"
# check if bd ini exists (a file with login credentials)
if [ -e $virtbdini ]; then
username=`cat $virtbdini | grep "^Username=" | cut -d "=" -f 2-`
password=`cat $virtbdini | grep "^Password=" | cut -d "=" -f 2-`
driver=`cat $virtbdini | grep "^Driver=" | cut -d "=" -f 2-`
address=`cat $virtbdini | grep "^Address=" | cut -d "=" -f 2-`
fi
# if we do not have the values we assume dba/dba and other well know values
if [ "$username" = "" ]; then
username="dba"
fi
if [ "$password" = "" ]; then
password="dba"
fi
if [ "$driver" = "" ]; then
driver="/usr/lib/odbc/virtodbc.so"
fi
if [ "$address" = "" ]; then
address="localhost:1111"
fi
### ODBC CONFIG
touch $odbcini
echo "# OntoWiki dsn start" >>$odbcini
echo "[$dsn]" >>$odbcini
echo Description=OntoWiki Virtuoso DSN >>$odbcini
echo Driver=$driver >>$odbcini
echo Address=$address >>$odbcini
echo "# OntoWiki dsn end" >>$odbcini
### ONTOWIKI CONFIG
chown www-data:www-data $owini
chmod 600 $owini
sed "s/%%DSN%%/$dsn/" -i $owini
sed "s/%%USERNAME%%/$username/" -i $owini
sed "s/%%PASSWORD%%/$password/" -i $owini
### VIRTUOSO CONFIG
# add ontowiki and erfurt directory to virtuoso.ini DirsAllowed
# try to remove the addition first in order to avoid double entries
sed 's/^\(DirsAllowed.*\)\(, \/usr\/share\/ontowiki\)\(.*\)/\1\3/' -i $virtuosoini
sed 's/^\(DirsAllowed.*\)/\1, \/usr\/share\/ontowiki/' -i $virtuosoini
sed 's/^\(DirsAllowed.*\)\(, \/usr\/share\/php\/liberfurt-php\)\(.*\)/\1\3/' -i $virtuosoini
sed 's/^\(DirsAllowed.*\)/\1, \/usr\/share\/php\/liberfurt-php/' -i $virtuosoini
### APACHE CONFIG
a2enmod rewrite
a2enmod env
service apache2 restart
#DEBHELPER#
echo "---- ending postinst $@"
================================================
FILE: debian/rules
================================================
#!/usr/bin/make -f
# -*- makefile -*-
# Sample debian/rules that uses debhelper.
# This file was originally written by Joey Hess and Craig Small.
# As a special exception, when this file is copied by dh-make into a
# dh-make output file, you may use that output file without restriction.
# This special exception was added by Craig Small in version 0.37 of dh-make.
# Uncomment this to turn on verbose mode.
#export DH_VERBOSE=1
%:
dh $@
================================================
FILE: debian/source/format
================================================
3.0 (native)
================================================
FILE: debian/sql/install/mysql
================================================
================================================
FILE: debian/sql/install/virtuoso
================================================
USER_CREATE('ontowiki_deb', 'usepwgenhere', vector ('SQL_ENABLE',1));
GRANT SELECT ON sys_rdf_schema TO ontowiki_deb;
GRANT execute ON rdfs_rule_set TO ontowiki_deb;
USER_GRANT_ROLE('ontowiki_deb', 'SPARQL_SELECT', 0);
USER_GRANT_ROLE('ontowiki_deb', 'SPARQL_UPDATE', 0);
USER_GRANT_ROLE('ontowiki_deb', 'administrators', 0);
================================================
FILE: extensions/account/AccountController.php
================================================
, Norman Heino
*/
class AccountController extends OntoWiki_Controller_Component
{
/**
* Handles identity recovery operations
*/
public function recoverAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$config = Erfurt_App::getInstance()->getConfig();
$translate = $this->_owApp->translate;
// start in phase 0
$phase = 0;
$success = true;
$translate = $this->_owApp->translate;
// check available params
// phase 1 is generation of hash taking recovery measures (mailing etc...)
$params['for'] = $this->getParam('for');
if (empty($params['for'])) {
unset($params['for']);
} else {
$this->view->identity = $params['for'];
$phase = 1;
}
// phase 2 for entering new password
$params['hash'] = $this->getParam('hash');
if (empty($params['hash'])) {
unset($params['hash']);
} else {
$this->view->hash = $params['hash'];
$phase = 2;
}
// phase 3 for cleanup and password change in ow system
$params['password_o'] = $this->getParam('password_o');
$params['password_r'] = $this->getParam('password_r');
if (empty($params['hash']) || empty($params['password_o']) || empty($params['password_r'])) {
unset($params['password_o']);
unset($params['password_r']);
} else {
$phase = 3;
}
$title = sprintf($translate->_('Account Recovery Stage %s'), ($phase + 1) . ' / 4');
$this->view->placeholder('main.window.title')->set($title);
$this->view->phase = $phase;
$recoveryObject = new Erfurt_Auth_Identity_Recovery();
try {
switch ($phase) {
case 0:
break;
case 1:
$userInfo = $recoveryObject->validateUser($params['for']);
$tplDir = $this->_componentRoot . 'templates/';
$userUri = $userInfo['userUri'];
$template = array();
$template['mailSubject'] = $translate->_('OntoWiki Account Recovery');
$template['mailTo'] = $userInfo[$config->ac->user->mail];
$template['mailUser'] = $userInfo[$config->ac->user->name];
$url = new OntoWiki_Url();
$url->setParam('controller', 'account');
$url->setParam('action', 'recover');
$url->setParam('hash', $userInfo['hash']);
$url->setParam('for', null);
$this->view->recoveryUrl = (string)$url;
$this->view->username = $userInfo[$config->ac->user->name];
$txtFile = 'mail/text/' . $this->_owApp->translate->getLocale() . '.txt';
if (file_exists($tplDir . $txtFile)) {
$template['contentText'] = $this->view->render($txtFile);
} else {
$template['contentText'] = $this->view->render('mail/text/default.txt');
}
$htmlFile = 'mail/html/' . $this->_owApp->translate->getLocale() . '.phtml';
if (file_exists($tplDir . $htmlFile)) {
$template['contentHtml'] = $this->view->render($htmlFile);
} else {
$template['contentHtml'] = $this->view->render('mail/html/default.phtml');
}
$recoveryObject->setTemplate($template);
$success = $recoveryObject->recoverWithIdentity($userUri);
break;
case 2:
$success = $recoveryObject->validateHash($params['hash']);
break;
case 3:
$success = $recoveryObject->resetPassword(
$params['hash'],
$params['password_o'],
$params['password_r']
);
break;
default:
break;
}
} catch (Erfurt_Exception $e) {
$success = false;
$message = $translate->_($e->getMessage());
$this->_owApp->appendMessage(
new OntoWiki_Message($message, OntoWiki_Message::ERROR)
);
}
// show toolbar if not in last phase and no errors occured
if ($success && $phase < 3) {
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Submit'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
if (!$success) {
$title = $translate->_('Account Recovery Error');
$this->view->placeholder('main.window.title')->set($title);
}
$this->view->success = $success;
$this->view->formActionUrl = $this->_config->urlBase . 'account/recover';
$this->view->formEncoding = 'multipart/form-data';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formMethod = 'post';
$this->view->formName = 'accountrecovery';
}
}
================================================
FILE: extensions/account/LoginModule.php
================================================
*/
class LoginModule extends OntoWiki_Module
{
/**
* Returns the message of the module
*
* @return array
*/
public function getMessage()
{
if ($authResult = $this->_owApp->authResult) {
// Translate partial messages before creation of message box
$translate = OntoWiki::getInstance()->translate;
$message = $translate->translate($authResult[0]);
$message .= ' '
. $translate->translate('Forgot your password?')
. ' ';
// create messagebox for loginbox (no escape for html code)
$message = new OntoWiki_Message(
$message,
OntoWiki_Message::ERROR,
array('escape' => false, 'translate' => false)
);
unset($this->_owApp->authResult);
return $message;
}
}
/**
* Returns the content for the model list.
*/
public function getContents()
{
$request = $this->_owApp->request;
$url = $request->getServer('REQUEST_URI');
$data = array(
'actionUrl' => $this->_config->urlBase . 'application/login',
'redirectUri' => urlencode((string)$url)
);
if ($this->_erfurt->getAc()->isActionAllowed('RegisterNewUser')
&& !(isset($this->_owApp->config->ac)
&& ((boolean)$this->_owApp->config->ac->deactivateRegistration === true))
) {
$data['showRegisterButton'] = true;
$data['registerActionUrl'] = $this->_config->urlBase . 'application/register';
$data['openIdRegisterActionUrl'] = $this->_config->urlBase . 'application/openidreg';
$data['webIdRegisterActionUrl'] = $this->_config->urlBase . 'application/webidreg';
} else {
$data['showRegisterButton'] = false;
}
// insert subtemplates according to the allow array in the config
$content = array();
foreach ($this->_privateConfig->allow as $template => $value) {
if ($value == 1) {
$content[$template] = $this->render('templates/' . $template, $data);
}
}
return $content;
}
public function shouldShow()
{
if ($this->_owApp->erfurt->getAc() instanceof Erfurt_Ac_None) {
return false;
}
if (!$this->_owApp->user || $this->_owApp->user->isAnonymousUser()) {
return true;
}
return false;
}
public function allowCaching()
{
// no caching
return false;
}
public function getTitle()
{
return "Login";
}
}
================================================
FILE: extensions/account/default.ini
================================================
;;
; Static module configuration
;;
enabled = true
name = "Login Module"
description = "provides a login module and a recover action."
author = "AKSW"
authorUrl = "http://aksw.org"
caching = yes
priority = 40
contexts[] = "main.sidewindows"
templates = "templates"
languages = "languages"
[private]
; local username + pass
allow.local = true
; remote WebIDs, currently broken
allow.webid = false
; remote OpenIDs
allow.openid = true
================================================
FILE: extensions/account/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :account .
:account a doap:Project ;
doap:name "account" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Login Module" ;
doap:description "provides a login module and a recover action." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:templates "templates" ;
owconfig:languages "languages" ;
owconfig:hasModule :Default .
:Default a owconfig:Module ;
rdfs:label "Default" ;
owconfig:caching "true"^^xsd:boolean ;
owconfig:priority "40" ;
owconfig:context "main.sidewindows" .
:account owconfig:config [
a owconfig:Config;
owconfig:id "allow";
:local "true"^^xsd:boolean ;
:webid "false"^^xsd:boolean ;
:openid "true"^^xsd:boolean
] ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/account/languages/account-de.csv
================================================
Account Recovery Stage %s;Account Wiederherstellung Abschnitt %s
Account Recovery Error;Account Wiederherstellung Fehler
Invalid recovery session identifier.;Ungültige Wiederherstellungssitzungskennung.
You received a mail with further information for account %s. Please follow these instructions to reset your password.;Sie haben eine E-Mail mit weiteren Informationen zu dem Account %s erhalten. Bitte folgen sie diesen Anweisungen um ihr Passwort wiederherzustellen.
You should able to login with your new password now.;Sie können sich nun mit ihrem neuen Passwort anmelden.
Username or email;Benutzername oder E-Mail
local;Lokal
openid;OpenID
webid;WebID
================================================
FILE: extensions/account/languages/account-en.csv
================================================
Account Recovery Stage %s
Account Recovery Error
Invalid recovery session identifier.
You received a mail with further information for account %s. Please follow these instructions to reset your password.
You should able to login with your new password now.
Username or email
local;Local
openid;OpenID
webid;WebID
================================================
FILE: extensions/account/templates/account/recover.phtml
================================================
* @author Philipp Frischmuth
* @author Christoph Rieß
*/
?>
success) { ?>
phase) {
case 0: ?>
_('You received a mail with further information for account %s. Please follow these instructions to reset your password.'); ?>
identity); ?>
_('You should able to login with your new password now.'); ?>
This is an automatic account recovery mail for OntoWiki
Please open the following
link
to reset the password for user username; ?>
Do not reply to this mail.
================================================
FILE: extensions/account/templates/mail/text/default.txt
================================================
This is an automatic account recovery mail for OntoWiki
Please open the following link : recoveryUrl; ?> to reset the password for user username; ?>
Do not reply to this mail.
================================================
FILE: extensions/account/templates/openid.phtml
================================================
================================================
FILE: extensions/account/templates/webid.phtml
================================================
================================================
FILE: extensions/application/ApplicationModule.php
================================================
_owApp->user instanceof Erfurt_Auth_Identity)) {
return $title;
}
if ($this->_owApp->user->isOpenId() || $this->_owApp->user->isWebId()) {
if ($this->_owApp->user->getLabel() !== '') {
$userName = $this->_owApp->user->getLabel();
$userName = OntoWiki_Utils::shorten($userName, 25);
} else {
$userName = OntoWiki_Utils::getUriLocalPart($this->_owApp->user->getUri());
$userName = OntoWiki_Utils::shorten($userName, 25);
}
} else {
if ($this->_owApp->user->getUsername() !== '') {
$userName = $this->_owApp->user->getUsername();
$userName = OntoWiki_Utils::shorten($userName, 25);
} else {
$userName = OntoWiki_Utils::getUriLocalPart($this->_owApp->user->getUri());
$userName = OntoWiki_Utils::shorten($userName, 25);
}
}
if (isset($userName) && $userName !== 'Anonymous') {
$title .= ' (' . $userName . ')';
}
return $title;
}
/**
* Maybe we should disable the app module in some case?
*
* @return string
*/
public function shouldShow()
{
if ($this->_privateConfig->hideForAnonymousOnNoModels
&& $this->_owApp->user->isAnonymousUser()
) {
// show only if there are models (visible or hidden)
if ($this->_store->getAvailableModels(true)) {
return true;
} else {
return false;
}
} else {
return true;
}
}
/**
* Returns the menu of the module
*
* @return string
*/
public function getMenu()
{
return OntoWiki_Menu_Registry::getInstance()->getMenu('application');
}
/**
* Returns the content for the model list.
*/
public function getContents()
{
$data = array(
'actionUrl' => $this->_config->urlBase . 'application/search/',
'modelSelected' => isset($this->_owApp->selectedModel),
'searchtextinput' => $this->_request->getParam('searchtext-input')
);
if (null !== ($logo = $this->_owApp->erfurt->getStore()->getLogoUri())) {
$data['logo'] = $logo;
$data['logo_alt'] = 'Store Logo';
}
if ($this->_owApp->selectedModel) {
$data['showSearch'] = true;
} else {
$data['showSearch'] = false;
}
$content = $this->render('application', $data);
return $content;
}
public function allowCaching()
{
// no caching
return false;
}
}
================================================
FILE: extensions/application/application.phtml
================================================
================================================
FILE: extensions/application/default.ini
================================================
;;
; Static module configuration
;;
enabled = true
name = "Application Module"
description = "provides the application module with search input and main menu."
author = "AKSW"
authorUrl = "http://aksw.org"
caching = no
priority = 1
contexts[] = "main.sidewindows"
[private]
; this option hides the application module for the anonymous user
; if there are no available models for the anonymous user
hideForAnonymousOnNoModels = no
================================================
FILE: extensions/application/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :application .
:application a doap:Project ;
doap:name "application" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Application Module" ;
doap:description "provides the application module with search input and main menu." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:hasModule :Default .
:Default a owconfig:Module ;
rdfs:label "Default" ;
owconfig:caching "false"^^xsd:boolean ;
owconfig:priority "1" ;
owconfig:context "main.sidewindows" .
:application :hideForAnonymousOnNoModels "false"^^xsd:boolean ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/auth/AuthController.php
================================================
*/
class AuthController extends OntoWiki_Controller_Component
{
public function certAction()
{
$translate = $this->_owApp->translate;
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->_helper->viewRenderer->setScriptAction('cert1');
$this->view->placeholder('main.window.title')->set($translate->_('Create Certificate - Step 1'));
require_once 'Erfurt/Auth/Adapter/FoafSsl.php';
if (!Erfurt_Auth_Adapter_FoafSsl::canCreateCertificates()) {
$this->view->errorFlag = true;
require_once 'OntoWiki/Message.php';
$this->_owApp->appendMessage(
new OntoWiki_Message(
$translate->_('The creation of self signed certificates is not supported.'),
OntoWiki_Message::ERROR
)
);
return;
}
$this->view->formActionUrl = $this->_config->urlBase . 'auth/cert';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'createcert';
$get = $this->_request->getQuery();
$post = $this->_request->getPost();
if (empty($get) && empty($post)) {
// Initial request... check whether a valid cert is already given and show message if yes.
$info = Erfurt_Auth_Adapter_FoafSsl::getCertificateInfo();
// If $info is false, we have no cert, so we can create one.
if ($info !== false) {
if (isset($info['foafPublicKey'])) {
// We have a valid id here... we need no cert.
$this->view->errorFlag = true;
require_once 'OntoWiki/Message.php';
$this->_owApp->appendMessage(
new OntoWiki_Message(
sprintf(
$translate->_(
'You already have a valid identity that you can use to sign in. ' .
'Your WebID is: %1$s'
),
$info['webId']
),
OntoWiki_Message::INFO,
array(
'escape' => false
)
)
);
return;
} else {
// We have a valid cert, but the foaf data does not contain the public key info... so show it.
$this->view->errorFlag = true;
$message = '' .
sprintf(
$translate->_(
'You already have a valid certificate, but the FOAF data behind your WebID ' .
'%1&s does not contain the right public key infos. You should add the ' .
'following infos to your FOAF profile:
Modulus
%2$s
' .
'Exponent
%3$s
',
$info['webId'],
$info['certPublicKey']['modulus'],
hexdec($info['certPublicKey']['exponent'])
)
) . '';
require_once 'OntoWiki/Message.php';
$this->_owApp->appendMessage(
new OntoWiki_Message(
$message,
OntoWiki_Message::INFO,
array(
'escape' => false
)
)
);
return;
}
}
// If we reach this, we can show the initial step, where the user enters a webid or generates one.
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => $translate->_('Check WebID')));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
return;
}
if (!empty($post)) {
if (isset($post['checkwebid'])) {
// Step 1: Check the WebID or create one...
$webId = $post['webid-input'];
if (trim($webId) === '') {
$this->view->name = '';
$this->view->email = '';
} else {
// Check for metadata
$foafData = Erfurt_Auth_Adapter_FoafSsl::getFoafData($webId);
if (isset($foafData[$webId]['http://xmlns.com/foaf/0.1/name'][0]['value'])) {
$this->view->name = $foafData[$webId]['http://xmlns.com/foaf/0.1/name'][0]['value'];
} else {
$this->view->name = '';
}
if (isset($foafData[$webId]['http://xmlns.com/foaf/0.1/mbox'][0]['value'])) {
$this->view->email = $foafData[$webId]['http://xmlns.com/foaf/0.1/mbox'][0]['value'];
} else {
$this->view->email = '';
}
if (isset($foafData[$webId]['http://xmlns.com/foaf/0.1/depiction'][0]['value'])) {
$this->view->depiction = $foafData[$webId]['http://xmlns.com/foaf/0.1/depiction'][0]['value'];
}
$this->view->webid = $webId;
}
// Show step 2
$this->_helper->viewRenderer->setScriptAction('cert2');
$this->view->placeholder('main.window.title')->set($translate->_('Create Certificate - Step 2'));
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(
OntoWiki_Toolbar::SUBMIT,
array('name' => htmlspecialchars($translate->_('Create Certificate & Register')))
);
$this->view->placeholder('main.window.toolbar')->set($toolbar);
// Message to inform the user that after cert creation he needs to reload
$message = $translate->_(
'Please note that you need to return to the start page after certificate creation.'
);
require_once 'OntoWiki/Message.php';
$this->_owApp->appendMessage(new OntoWiki_Message($message, OntoWiki_Message::INFO));
return;
}
if (isset($post['createcert'])) {
// Step2: Create the cert...
$name = $post['name-input'];
if (trim($name) === '') {
// We need a name!
$this->view->errorFlag = true;
require_once 'OntoWiki/Message.php';
$this->_owApp->appendMessage(
new OntoWiki_Message(
$translate->_('The name field must not be empty.'),
OntoWiki_Message::ERROR
)
);
return;
}
if (isset($post['webid-input'])) {
// WebId given
$webId = $post['webid-input'];
} else {
// Autogenerate WebId
$webId = $this->_generateWebId(str_replace(' ', '', $name));
}
$email = trim($post['email-input']);
if ($email !== '' && substr($email, 0, 7) !== 'mailto:') {
$email = 'mailto:' . $email;
}
$cert = Erfurt_Auth_Adapter_FoafSsl::createCertificate(
$webId,
$name,
$email,
$post['pubkey']
);
// Add the user...
$auth = new Erfurt_Auth_Adapter_FoafSsl();
$success = $auth->addUser($webId);
if ($success !== false) {
$store = Erfurt_App::getInstance()->getStore();
$bnodePrefix = '_:' . md5($webId);
$nodeA = $bnodePrefix . '_1';
$nodeB = $bnodePrefix . '_2';
$nodeC = $bnodePrefix . '_3';
$stmtArray = array(
$nodeA => array(
EF_RDF_TYPE => array(array(
'type' => 'uri',
'value' => 'http://www.w3.org/ns/auth/rsa#RSAPublicKey'
)),
'http://www.w3.org/ns/auth/cert#identity' => array(array(
'type' => 'uri',
'value' => $webId
)),
'http://www.w3.org/ns/auth/rsa#public_exponent' => array(array(
'type' => 'bnode',
'value' => $nodeB
)),
'http://www.w3.org/ns/auth/rsa#modulus' => array(array(
'type' => 'bnode',
'value' => $nodeC
))
),
$nodeB => array(
'http://www.w3.org/ns/auth/cert#decimal' => array(array(
'type' => 'literal',
'value' => $cert['exponent']
))
),
$nodeC => array(
'http://www.w3.org/ns/auth/cert#hex' => array(array(
'type' => 'literal',
'value' => $cert['modulus']
))
)
);
$store->addMultipleStatements('http://localhost/OntoWiki/Config/', $stmtArray, false);
}
header("Content-Type: application/x-x509-user-cert");
echo $cert['certData'];
return;
}
}
$config = $this->_config;
$this->view->formActionUrl = $this->_config->urlBase . 'auth/cert';
$this->view->formMethod = 'post';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formName = 'createcert';
$this->view->username = '';
$this->view->readonly = '';
$this->view->email = '';
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => $translate->_('Create Certificate')))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => $translate->_('Reset Form')));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
public function usersAction()
{
// TODO Make sure that no sensilbe information (pw) is exported...
$this->_helper->viewRenderer->setNoRender();
$this->_helper->layout->disableLayout();
if (null === $this->_request->id) {
echo '"id" parameter is missing.';
return;
}
$id = $this->_config->urlBase . 'auth/users/id/' . $this->_request->id;
$modelUri = 'http://localhost/OntoWiki/Config/';
$store = $this->_erfurt->getStore();
require_once 'Erfurt/Syntax/RdfSerializer.php';
$serializer = Erfurt_Syntax_RdfSerializer::rdfSerializerWithFormat('rdfxml');
echo $serializer->serializeResourceToString($id, $modelUri, false, false);
$response = $this->getResponse();
$response->setHeader('Content-Type', 'application/rdf+xml', true);
}
public function agentAction()
{
// TODO Do this in a more dynamic way...
echo '';
$response = $this->getResponse();
$response->setHeader('Content-Type', 'application/rdf+xml', true);
}
private function _generateWebId($suffix = '')
{
$base = $this->_config->urlBase . 'auth/users/id/';
$users = Erfurt_App::getInstance()->getUsers();
$url = $base . $suffix;
if (!isset($users[$url])) {
return $url;
} else {
$i = 0;
$urlB = $url . $i;
while (true) {
if (!isset($users[$urlB])) {
return $urlB;
} else {
++$i;
$urlB = $url . $i;
}
}
}
}
}
================================================
FILE: extensions/auth/default.ini
================================================
enabled = true
templates = "templates/"
languages = "languages/"
name = "Authentification"
description = "provides WebID and FOAF+SSL authentification."
author = "AKSW"
authorUrl = "http://aksw.org"
[private]
auth.agentId = "https://localhost/ow_da/auth/agent"
auth.exponent = "65537"
auth.modulus = "cd98a73faf90a4013ef0477b679fe4415b8c4504823e7586a961dab8a35596fcb1803a4b4966f2515320bada80bbc61342f97405b41fdac4140ddbb12fa360befb71482a6cf886991bda3039ef7ce7fa73c9ecc7796cd3f30ce9726dce1977b426c616b6fae11af480cddf051d8631814006508a377e14fb3c8360cb615989a7"
================================================
FILE: extensions/auth/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :auth .
:auth a doap:Project ;
doap:name "auth" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
owconfig:templates "templates/" ;
owconfig:languages "languages/" ;
rdfs:label "Authentification" ;
doap:description "provides WebID and FOAF+SSL authentification." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:config [
a owconfig:Config;
owconfig:id "auth";
:agentId ;
:exponent "65537" ;
:modulus "cd98a73faf90a4013ef0477b679fe4415b8c4504823e7586a961dab8a35596fcb1803a4b4966f2515320bada80bbc61342f97405b41fdac4140ddbb12fa360befb71482a6cf886991bda3039ef7ce7fa73c9ecc7796cd3f30ce9726dce1977b426c616b6fae11af480cddf051d8631814006508a377e14fb3c8360cb615989a7"
] ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/auth/languages/auth-de.csv
================================================
The creation of self signed certificates is not supported.;The creation of self signed certificates is not supported.
You already have a valid identity that you can use to sign in. Your WebID is: %1$s;Sie besitzen bereits ein gültiges Zertifikat. Nutzen Sie dieses, um sich anzumelden. Ihre WebID lautet: %1$s
You already have a valid certificate, but the FOAF data behind your WebID %1&s does not contain the right public key infos. You should add the following infos to your FOAF profile:
Modulus
%2$s
Exponent
%3$s
;Sie besitzen bereits ein gültiges Zertifikat, aber die zugehörigen FOAF-Daten (%1&s) enthalten nicht die richtigen Informationen über den öffentlichen Schlüssel. Sie sollten die folgenden Informationen zu Ihren FOAF-Daten hinzufügen:
Modulus
%2$s
Exponent
%3$s
Create Certificate - Step 1;Zertifikat erstellen - Schritt 1
Check WebID;WebID prüfen
Create Certificate - Step 2;Zertifikat erstellen - Schritt 2
Create Certificate & Register;Zertifikat erstellen & Registrieren
The name field must not be empty.;Das Eingabefeld für den Namen darf nicht leer sein.
Reset Form;Formular zurücksetzen
If not provided a WebID will be generated.;Wenn Sie keine WebID angeben, wird automatisch eine erstellt.
WebID;WebID
Name;Ihr Name
Email;Email
Please note that you need to return to the start page after certificate creation.;Bitte beachten Sie, dass Sie nach der Erstellung des Zertifikats zur Startseite zurückkehren müssen.
================================================
FILE: extensions/auth/languages/auth-en.csv
================================================
The creation of self signed certificates is not supported.;The creation of self signed certificates is not supported.
You already have a valid identity that you can use to sign in. Your WebID is: %1$s;You already have a valid identity that you can use to sign in. Your WebID is: %1$s
You already have a valid certificate, but the FOAF data behind your WebID %1&s does not contain the right public key infos. You should add the following infos to your FOAF profile:
Modulus
%2$s
Exponent
%3$s
;You already have a valid certificate, but the FOAF data behind your WebID %1&s does not contain the right public key infos. You should add the following infos to your FOAF profile:
Modulus
%2$s
Exponent
%3$s
Create Certificate - Step 1;Create Certificate - Step 1
Check WebID;Check WebID
Create Certificate - Step 2;Create Certificate - Step 2
Create Certificate & Register;Create Certificate & Register
The name field must not be empty.;The name field must not be empty.
Reset Form;Reset Form
If not provided a WebID will be generated.;If not provided a WebID will be generated.
WebID;WebID
Name;Your Name
Email;Email
Please note that you need to return to the start page after certificate creation.;Please note that you need to return to the start page after certificate creation.
================================================
FILE: extensions/auth/templates/auth/cert1.phtml
================================================
* @author Philipp Frischmuth
* @version $Id: userdetails.phtml 2917 2009-04-21 12:13:33Z norman.heino $
*/
?>
errorFlag)): ?>
================================================
FILE: extensions/auth/templates/auth/cert2.phtml
================================================
* @author Philipp Frischmuth
* @version $Id: userdetails.phtml 2917 2009-04-21 12:13:33Z norman.heino $
*/
?>
errorFlag)): ?>
================================================
FILE: extensions/autologin/AutologinPlugin.php
================================================
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class AutologinPlugin extends OntoWiki_Plugin
{
public function onRouteShutdown($event)
{
if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on' && extension_loaded('openssl')) {
$app = Erfurt_App::getInstance();
if ($app->getAuth()->getIdentity()->isAnonymousUser()) {
$result = $app->authenticateWithFoafSsl();
if ($result->isValid()) {
// Redirect to referer page...
require_once 'Zend/Controller/Front.php';
$front = Zend_Controller_Front::getInstance()->getResponse()->setRedirect($_SERVER['HTTP_REFERER']);
}
}
}
}
}
================================================
FILE: extensions/autologin/default.ini
================================================
enabled = false
name = AutoLogin
description = "A plug-in that allows FOAF+SSL based auto login."
author = "Philipp Frischmuth"
[events]
1 = onRouteShutdown
[private]
================================================
FILE: extensions/autologin/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :autologin .
:autologin a doap:Project ;
doap:name "autologin" ;
owconfig:privateNamespace ;
owconfig:enabled "false"^^xsd:boolean ;
rdfs:label "AutoLogin" ;
doap:description "A plug-in that allows FOAF+SSL based auto login." ;
owconfig:authorLabel "Philipp Frischmuth" ;
owconfig:pluginEvent event:onRouteShutdown ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/basicimporter/BasicimporterController.php
================================================
*/
class BasicimporterController extends OntoWiki_Controller_Component
{
private $_model = null;
private $_post = null;
/**
* init() Method to init() normal and add tabbed Navigation
*/
public function init()
{
parent::init();
OntoWiki::getInstance()->getNavigation()->disableNavigation();
// provide basic view data
$action = $this->_request->getActionName();
$this->view->placeholder('main.window.title')->set('Import Data');
$this->view->formActionUrl = $this->_config->urlBase . 'basicimporter/' . $action;
$this->view->formEncoding = 'multipart/form-data';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formMethod = 'post';
$this->view->formName = 'importdata';
$this->view->supportedFormats = $this->_erfurt->getStore()->getSupportedImportFormats();
if (!$this->isSelectedModelEditable()) {
return;
} else {
$this->_model = $this->_owApp->selectedModel;
}
// add a standard toolbar
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(
OntoWiki_Toolbar::SUBMIT,
array('name' => 'Import Data', 'id' => 'importdata')
)->appendButton(
OntoWiki_Toolbar::RESET,
array('name' => 'Cancel', 'id' => 'importdata')
);
$this->view->placeholder('main.window.toolbar')->set($toolbar);
if ($this->_request->isPost()) {
$this->_post = $this->_request->getPost();
}
}
public function rdfpasterAction()
{
$this->view->placeholder('main.window.title')->set('Paste RDF Content');
if ($this->_request->isPost()) {
$post = $this->_request->getPost();
$filetype = $post['filetype-paste'];
$file = tempnam(sys_get_temp_dir(), 'ow');
$temp = fopen($file, 'wb');
fwrite($temp, $this->getParam('paste'));
fclose($temp);
$locator = Erfurt_Syntax_RdfParser::LOCATOR_FILE;
try {
$this->_import($file, $filetype, $locator);
} catch (Exception $e) {
$message = $e->getMessage();
$this->_owApp->appendErrorMessage($message);
return;
}
$this->_owApp->appendSuccessMessage('Data successfully imported.');
}
}
public function rdfwebimportAction()
{
$this->view->placeholder('main.window.title')->set('Import RDF from the Web');
$this->addModuleContext('main.window.basicimporter.rdfwebimport');
if ($this->_request->isPost()) {
$postData = $this->_request->getPost();
$location = $postData['location'] != '' ? $postData['location'] : (string)$this->_model;
} else {
// walkthrough paramater is added by the SelectorModule
if ($this->_request->getParam('importOptions') == 'walkthrough') {
// use model uri as location
$location = $this->_request->getParam('m');
}
}
if (isset($location)) {
try {
$filetype = 'rdfxml';
$locator = Erfurt_Syntax_RdfParser::LOCATOR_URL;
$this->_import($location, $filetype, $locator);
} catch (Exception $e) {
$message = $e->getMessage();
$this->_owApp->appendErrorMessage($message);
return;
}
$this->_owApp->appendSuccessMessage('Data from ' . $location . ' successfully imported.');
// redirect to model info
if ($this->_request->getParam('importOptions') == 'walkthrough') {
$url = new OntoWiki_Url(
array(
'controller' => 'model',
'action' => 'info'
)
);
$this->_redirect($url, array('code' => 302));
}
}
}
public function rdfuploadAction()
{
$this->view->placeholder('main.window.title')->set('Upload RDF Dumps');
if ($this->_request->isPost()) {
$postData = $this->_request->getPost();
$upload = new Zend_File_Transfer();
$filesArray = $upload->getFileInfo();
$message = '';
switch (true) {
case empty($filesArray):
$message = 'upload went wrong. check post_max_size in your php.ini.';
break;
case ($filesArray['source']['error'] == UPLOAD_ERR_INI_SIZE):
$message = 'The uploaded files\'s size exceeds the upload_max_filesize directive in php.ini.';
break;
case ($filesArray['source']['error'] == UPLOAD_ERR_PARTIAL):
$message = 'The file was only partially uploaded.';
break;
case ($filesArray['source']['error'] >= UPLOAD_ERR_NO_FILE):
$message = 'Please select a file to upload';
break;
}
if ($message != '') {
$this->_owApp->appendErrorMessage($message);
return;
}
$file = $filesArray['source']['tmp_name'];
// setting permissions to read the tempfile for everybody
// (e.g. if db and webserver owned by different users)
chmod($file, 0644);
$locator = Erfurt_Syntax_RdfParser::LOCATOR_FILE;
$filetype = 'auto';
// guess file mime type
if ($postData['filetype-upload'] != 'auto') {
$filetype = $postData['filetype-upload'];
} else {
// guess file type extension
$extension = strtolower(strrchr($filesArray['source']['name'], '.'));
if ($extension == '.rdf' || $extension == '.owl') {
$filetype = 'rdfxml';
} else if ($extension == '.n3') {
$filetype = 'ttl';
} else if ($extension == '.json') {
$filetype = 'rdfjson';
} else if ($extension == '.ttl') {
$filetype = 'ttl';
} else if ($extension == '.nt') {
$filetype = 'ttl';
}
}
try {
$this->_import($file, $filetype, $locator);
} catch (Exception $e) {
$message = $e->getMessage();
$this->_owApp->appendErrorMessage($message);
return;
}
$this->_owApp->appendSuccessMessage('Data successfully imported.');
}
}
private function _import($fileOrUrl, $filetype, $locator)
{
$modelIri = (string)$this->_model;
try {
$this->_erfurt->getStore()->importRdf($modelIri, $fileOrUrl, $filetype, $locator);
} catch (Erfurt_Exception $e) {
// re-throw
throw new OntoWiki_Controller_Exception(
'Could not import given model: ' . $e->getMessage(),
0,
$e
);
}
}
}
================================================
FILE: extensions/basicimporter/BasicimporterPlugin.php
================================================
*/
class BasicimporterPlugin extends OntoWiki_Plugin
{
/*
* our event method
*/
public function onProvideImportActions($event)
{
$this->provideImportActions($event);
}
/**
* Listen for the store initialization event
*/
public function onSetupStore($event)
{
// $this->importModels();
}
/*
* here we add new import actions
*/
private function provideImportActions($event)
{
$myImportActions = array(
'basicimporter-rdfweb' => array(
'controller' => 'basicimporter',
'action' => 'rdfwebimport',
'label' => 'Import an RDF resource from the web',
'description' => 'Tries to fetch a graph from the web.'
),
'basicimporter-rdfupload' => array(
'controller' => 'basicimporter',
'action' => 'rdfupload',
'label' => 'Upload an RDF Dump',
'description' => 'Parse and import turtle, ntriples, rdfxml and other dumps.'
),
'basicimporter-rdfpaster' => array(
'controller' => 'basicimporter',
'action' => 'rdfpaster',
'label' => 'Paste Source',
'description' => 'Parses and import turtle, ntriples and rdfxml import from a textfield.'
),
);
// sad but true, some php installation do not allow this
if (!ini_get('allow_url_fopen')) {
unset($myImportActions['basicimporter-rdfwebimport']);
}
$event->importActions = array_merge($event->importActions, $myImportActions);
return $event;
}
private function importModels()
{
// read config for models to import
$owApp = OntoWiki::getInstance();
$models = $this->_privateConfig->setup->model->toArray();
foreach ($models as $info) {
// import models
$path = ONTOWIKI_ROOT . '/' . $info['path'];
$uri = $info['uri'];
$hidden = $info['hidden'];
$this->_import($uri, $path);
}
}
private function _import($modelIri, $fileOrUrl)
{
try {
Erfurt_App::getInstance()->getStore()->importRdf($modelIri, $fileOrUrl);
} catch (Erfurt_Exception $e) {
// re-throw
throw new OntoWiki_Controller_Exception(
'Could not import given model: ' . $e->getMessage(),
0,
$e
);
}
}
}
================================================
FILE: extensions/basicimporter/SelectorModule.js
================================================
/*global document,$,alert,console */
/*jslint browser: true, vars: true, plusplus: true */
/**
* This file is part of the {@link http://ontowiki.net OntoWiki} project.
*
* @copyright Copyright (c) 2013, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
/**
* OntoWiki module - selector module script compontent
*
* @category OntoWiki
* @package OntoWiki_Extensions_basicimporter
* @author Sebastian Tramp
*/
$(document).ready(function () {
'use strict';
/* defined entry points */
var lovSearchInput = $("#lov-search-input"),
lovSearchResults = $(".lov-search-result");
/*
* convert xml (esp. sparql xml resultset) to json objects
* http://stackoverflow.com/questions/7769829/
* */
var xmlToJson = function (xml) {
var obj = {};
if (xml.nodeType === 1) {
if (xml.attributes.length > 0) {
var j = 0;
obj["@attributes"] = {};
for (j = 0; j < xml.attributes.length; j++) {
var attribute = xml.attributes.item(j);
obj["@attributes"][attribute.nodeName] = attribute.nodeValue;
}
}
} else if (xml.nodeType === 3) {
obj = xml.nodeValue;
}
if (xml.hasChildNodes()) {
var i = 0;
for (i = 0; i < xml.childNodes.length; i++) {
var item = xml.childNodes.item(i);
var nodeName = item.nodeName;
if (typeof (obj[nodeName]) === "undefined") {
obj[nodeName] = xmlToJson(item);
} else {
if (typeof (obj[nodeName].push) === "undefined") {
var old = obj[nodeName];
obj[nodeName] = [];
obj[nodeName].push(old);
}
obj[nodeName].push(xmlToJson(item));
}
}
}
return obj;
};
var flushSchemaTable = function (data, textStatus, jqXHR, callback) {
var xmlDocument = xmlToJson(data),
results = xmlDocument.sparql.results.result,
i = 0;
if ((typeof results !== 'undefined') && (results.length > 0)) {
var prefix, namespace, title;
for (i = 0; i < results.length; i++) {
prefix = results[i].binding[0].literal['#text'];
namespace = results[i].binding[1].uri['#text'];
title = results[i].binding[2].literal['#text'];
// create list
//
* @before $.metadata.setType("elem", "script")
* @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label"
* @desc Reads metadata from a nested script element
*
* @param String type The encoding type
* @param String name The name of the attribute to be used to get metadata (optional)
* @cat Plugins/Metadata
* @descr Sets the type of encoding to be used when loading metadata for the first time
* @type undefined
* @see metadata()
*/
(function($) {
$.extend({
metadata : {
defaults : {
type: 'class',
name: 'metadata',
cre: /({.*})/,
single: 'metadata'
},
setType: function( type, name ){
this.defaults.type = type;
this.defaults.name = name;
},
get: function( elem, opts ){
var settings = $.extend({},this.defaults,opts);
// check for empty string in single property
if ( !settings.single.length ) settings.single = 'metadata';
var data = $.data(elem, settings.single);
// returned cached data if it already exists
if ( data ) return data;
data = "{}";
if ( settings.type == "class" ) {
var m = settings.cre.exec( elem.className );
if ( m )
data = m[1];
} else if ( settings.type == "elem" ) {
if( !elem.getElementsByTagName ) return;
var e = elem.getElementsByTagName(settings.name);
if ( e.length )
data = $.trim(e[0].innerHTML);
} else if ( elem.getAttribute != undefined ) {
var attr = elem.getAttribute( settings.name );
if ( attr )
data = attr;
}
if ( data.indexOf( '{' ) <0 )
data = "{" + data + "}";
data = eval("(" + data + ")");
$.data( elem, settings.single, data );
return data;
}
}
});
/**
* Returns the metadata object for the first member of the jQuery object.
*
* @name metadata
* @descr Returns element's metadata object
* @param Object opts An object contianing settings to override the defaults
* @type jQuery
* @cat Plugins/Metadata
*/
$.fn.metadata = function( opts ){
return $.metadata.get( this[0], opts );
};
})(jQuery);
================================================
FILE: extensions/community/jquery.rating.css
================================================
/* jQuery.Rating Plugin CSS - http://www.fyneworks.com/jquery/star-rating/ */
div.rating-cancel,div.star-rating{float:left;width:17px;height:15px;text-indent:-999em;cursor:pointer;display:block;background:transparent;overflow:hidden}
div.rating-cancel,div.rating-cancel a{background:url(delete.gif) no-repeat 0 -16px}
div.star-rating,div.star-rating a{background:url(star.gif) no-repeat 0 0px}
div.rating-cancel a,div.star-rating a{display:block;width:16px;height:100%;background-position:0 0px;border:0}
div.star-rating-on a{background-position:0 -16px!important}
div.star-rating-hover a{background-position:0 -32px}
/* Read Only CSS */
div.star-rating-readonly a{cursor:default !important}
/* Partial Star CSS */
div.star-rating{background:transparent!important;overflow:hidden!important}
/* END jQuery.Rating Plugin CSS */
================================================
FILE: extensions/community/jquery.rating.js
================================================
/*
### jQuery Star Rating Plugin v3.12 - 2009-04-16 ###
* Home: http://www.fyneworks.com/jquery/star-rating/
* Code: http://code.google.com/p/jquery-star-rating-plugin/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
###
*/
/*# AVOID COLLISIONS #*/
;if(window.jQuery) (function($){
/*# AVOID COLLISIONS #*/
// IE6 Background Image Fix
if ($.browser.msie) try { document.execCommand("BackgroundImageCache", false, true)} catch(e) { };
// Thanks to http://www.visualjquery.com/rating/rating_redux.html
// plugin initialization
$.fn.rating = function(options){
if(this.length==0) return this; // quick fail
// Handle API methods
if(typeof arguments[0]=='string'){
// Perform API methods on individual elements
if(this.length>1){
var args = arguments;
return this.each(function(){
$.fn.rating.apply($(this), args);
});
};
// Invoke API method handler
$.fn.rating[arguments[0]].apply(this, $.makeArray(arguments).slice(1) || []);
// Quick exit...
return this;
};
// Initialize options for this call
var options = $.extend(
{}/* new object */,
$.fn.rating.options/* default options */,
options || {} /* just-in-time options */
);
// Allow multiple controls with the same name by making each call unique
$.fn.rating.calls++;
// loop through each matched element
this
.not('.star-rating-applied')
.addClass('star-rating-applied')
.each(function(){
// Load control parameters / find context / etc
var control, input = $(this);
var eid = (this.name || 'unnamed-rating').replace(/\[|\]/g, '_').replace(/^\_+|\_+$/g,'');
var context = $(this.form || document.body);
// FIX: http://code.google.com/p/jquery-star-rating-plugin/issues/detail?id=23
var raters = context.data('rating');
if(!raters || raters.call!=$.fn.rating.calls) raters = { count:0, call:$.fn.rating.calls };
var rater = raters[eid];
// if rater is available, verify that the control still exists
if(rater) control = rater.data('rating');
if(rater && control)//{// save a byte!
// add star to control if rater is available and the same control still exists
control.count++;
//}// save a byte!
else{
// create new control if first star or control element was removed/replaced
// Initialize options for this raters
control = $.extend(
{}/* new object */,
options || {} /* current call options */,
($.metadata? input.metadata(): ($.meta?input.data():null)) || {}, /* metadata options */
{ count:0, stars: [], inputs: [] }
);
// increment number of rating controls
control.serial = raters.count++;
// create rating element
rater = $('');
input.before(rater);
// Mark element for initialization (once all stars are ready)
rater.addClass('rating-to-be-drawn');
// Accept readOnly setting from 'disabled' property
if(input.attr('disabled')) control.readOnly = true;
// Create 'cancel' button
rater.append(
control.cancel = $('
')
.mouseover(function(){
$(this).rating('drain');
$(this).addClass('star-rating-hover');
//$(this).rating('focus');
})
.mouseout(function(){
$(this).rating('draw');
$(this).removeClass('star-rating-hover');
//$(this).rating('blur');
})
.click(function(){
$(this).rating('select');
})
.data('rating', control)
);
}; // first element of group
// insert rating star
var star = $('
');
rater.append(star);
// inherit attributes from input element
if(this.id) star.attr('id', this.id);
if(this.className) star.addClass(this.className);
// Half-stars?
if(control.half) control.split = 2;
// Prepare division control
if(typeof control.split=='number' && control.split>0){
var stw = ($.fn.width ? star.width() : 0) || control.starWidth;
var spi = (control.count % control.split), spw = Math.floor(stw/control.split);
star
// restrict star's width and hide overflow (already in CSS)
.width(spw)
// move the star left by using a negative margin
// this is work-around to IE's stupid box model (position:relative doesn't work)
.find('a').css({ 'margin-left':'-'+ (spi*spw) +'px' })
};
// readOnly?
if(control.readOnly)//{ //save a byte!
// Mark star as readOnly so user can customize display
star.addClass('star-rating-readonly');
//} //save a byte!
else//{ //save a byte!
// Enable hover css effects
star.addClass('star-rating-live')
// Attach mouse events
.mouseover(function(){
$(this).rating('fill');
$(this).rating('focus');
})
.mouseout(function(){
$(this).rating('draw');
$(this).rating('blur');
})
.click(function(){
$(this).rating('select');
})
;
//}; //save a byte!
// set current selection
if(this.checked) control.current = star;
// hide input element
input.hide();
// backward compatibility, form element to plugin
input.change(function(){
$(this).rating('select');
});
// attach reference to star to input element and vice-versa
star.data('rating.input', input.data('rating.star', star));
// store control information in form (or body when form not available)
control.stars[control.stars.length] = star[0];
control.inputs[control.inputs.length] = input[0];
control.rater = raters[eid] = rater;
control.context = context;
input.data('rating', control);
rater.data('rating', control);
star.data('rating', control);
context.data('rating', raters);
}); // each element
// Initialize ratings (first draw)
$('.rating-to-be-drawn').rating('draw').removeClass('rating-to-be-drawn');
return this; // don't break the chain...
};
/*--------------------------------------------------------*/
/*
### Core functionality and API ###
*/
$.extend($.fn.rating, {
// Used to append a unique serial number to internal control ID
// each time the plugin is invoked so same name controls can co-exist
calls: 0,
focus: function(){
var control = this.data('rating'); if(!control) return this;
if(!control.focus) return this; // quick fail if not required
// find data for event
var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
// focus handler, as requested by focusdigital.co.uk
if(control.focus) control.focus.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
}, // $.fn.rating.focus
blur: function(){
var control = this.data('rating'); if(!control) return this;
if(!control.blur) return this; // quick fail if not required
// find data for event
var input = $(this).data('rating.input') || $( this.tagName=='INPUT' ? this : null );
// blur handler, as requested by focusdigital.co.uk
if(control.blur) control.blur.apply(input[0], [input.val(), $('a', input.data('rating.star'))[0]]);
}, // $.fn.rating.blur
fill: function(){ // fill to the current mouse position.
var control = this.data('rating'); if(!control) return this;
// do not execute when control is in read-only mode
if(control.readOnly) return;
// Reset all stars and highlight them up to this element
this.rating('drain');
this.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-hover');
},// $.fn.rating.fill
drain: function() { // drain all the stars.
var control = this.data('rating'); if(!control) return this;
// do not execute when control is in read-only mode
if(control.readOnly) return;
// Reset all stars
control.rater.children().filter('.rater-'+ control.serial).removeClass('star-rating-on').removeClass('star-rating-hover');
},// $.fn.rating.drain
draw: function(){ // set value and stars to reflect current selection
var control = this.data('rating'); if(!control) return this;
// Clear all stars
this.rating('drain');
// Set control value
if(control.current){
control.current.data('rating.input').attr('checked','checked');
control.current.prevAll().andSelf().filter('.rater-'+ control.serial).addClass('star-rating-on');
}
else
$(control.inputs).removeAttr('checked');
// Show/hide 'cancel' button
control.cancel[control.readOnly || control.required?'hide':'show']();
// Add/remove read-only classes to remove hand pointer
this.siblings()[control.readOnly?'addClass':'removeClass']('star-rating-readonly');
},// $.fn.rating.draw
select: function(value){ // select a value
var control = this.data('rating'); if(!control) return this;
// do not execute when control is in read-only mode
if(control.readOnly) return;
// clear selection
control.current = null;
// programmatically (based on user input)
if(typeof value!='undefined'){
// select by index (0 based)
if(typeof value=='number')
return $(control.stars[value]).rating('select');
// select by literal value (must be passed as a string
if(typeof value=='string')
//return
$.each(control.stars, function(){
if($(this).data('rating.input').val()==value) $(this).rating('select');
});
}
else
control.current = this[0].tagName=='INPUT' ?
this.data('rating.star') :
(this.is('.rater-'+ control.serial) ? this : null);
// Update rating control state
this.data('rating', control);
// Update display
this.rating('draw');
// find data for event
var input = $( control.current ? control.current.data('rating.input') : null );
// click callback, as requested here: http://plugins.jquery.com/node/1655
if(control.callback) control.callback.apply(input[0], [input.val(), $('a', control.current)[0]]);// callback event
},// $.fn.rating.select
readOnly: function(toggle, disable){ // make the control read-only (still submits value)
var control = this.data('rating'); if(!control) return this;
// setread-only status
control.readOnly = toggle || toggle==undefined ? true : false;
// enable/disable control value submission
if(disable) $(control.inputs).attr("disabled", "disabled");
else $(control.inputs).removeAttr("disabled");
// Update rating control state
this.data('rating', control);
// Update display
this.rating('draw');
},// $.fn.rating.readOnly
disable: function(){ // make read-only and never submit value
this.rating('readOnly', true, true);
},// $.fn.rating.disable
enable: function(){ // make read/write and submit value
this.rating('readOnly', false, false);
}// $.fn.rating.select
});
/*--------------------------------------------------------*/
/*
### Default Settings ###
eg.: You can override default control like this:
$.fn.rating.options.cancel = 'Clear';
*/
$.fn.rating.options = { //$.extend($.fn.rating, { options: {
cancel: 'Cancel Rating', // advisory title for the 'cancel' link
cancelValue: '', // value to submit when user click the 'cancel' link
split: 0, // split the star into how many parts?
// Width of star image in case the plugin can't work it out. This can happen if
// the jQuery.dimensions plugin is not available OR the image is hidden at installation
starWidth: 16//,
//NB.: These don't need to be pre-defined (can be undefined/null) so let's save some code!
//half: false, // just a shortcut to control.split = 2
//required: false, // disables the 'cancel' button so user can only select one of the specified values
//readOnly: false, // disable rating plugin interaction/ values cannot be changed
//focus: function(){}, // executed when stars are focused
//blur: function(){}, // executed when stars are focused
//callback: function(){}, // executed when a star is clicked
}; //} });
/*--------------------------------------------------------*/
/*
### Default implementation ###
The plugin will attach itself to file inputs
with the class 'multi' when the page loads
*/
$(function(){
$('input[type=radio].star').rating();
});
/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/
================================================
FILE: extensions/community/jquery.rating.pack.js
================================================
/*
### jQuery Star Rating Plugin v3.12 - 2009-04-16 ###
* Home: http://www.fyneworks.com/jquery/star-rating/
* Code: http://code.google.com/p/jquery-star-rating-plugin/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
###
*/
eval(function(p,a,c,k,e,r){e=function(c){return(c35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}(';5(1O.1t)(7($){5($.29.1x)1I{1m.23("1u",P,z)}1F(e){}$.p.4=7(j){5(3.K==0)l 3;5(E J[0]==\'1j\'){5(3.K>1){8 k=J;l 3.W(7(){$.p.4.H($(3),k)})};$.p.4[J[0]].H(3,$.1T(J).21(1)||[]);l 3};8 j=$.10({},$.p.4.18,j||{});3.1v(\'.9-4-1l\').n(\'9-4-1l\').W(7(){8 a=(3.1J||\'1K-4\').1L(/\\[|\\]+/g,"1S");8 b=$(3.1U||1m.1X);8 c=$(3);8 d=b.6(\'4\')||{y:0};8 e=d[a];8 f;5(e)f=e.6(\'4\');5(e&&f){f.y++}B{f=$.10({},j||{},($.1k?c.1k():($.1H?c.6():s))||{},{y:0,C:[],u:[]});f.t=d.y++;e=$(\'<1M 12="9-4-1Q"/>\');c.1R(e);e.n(\'4-T-13-S\');5(c.R(\'Q\'))f.m=z;e.1a(f.A=$(\'\'+f.15+\'\').1d(7(){$(3).4(\'N\');$(3).n(\'9-4-M\')}).1b(7(){$(3).4(\'v\');$(3).D(\'9-4-M\')}).1h(7(){$(3).4(\'w\')}).6(\'4\',f))};8 g=$(\'\'+3.1p+\'\');e.1a(g);5(3.U)g.R(\'U\',3.U);5(3.17)g.n(3.17);5(f.1V)f.x=2;5(E f.x==\'19\'&&f.x>0){8 h=($.p.11?g.11():0)||f.1c;8 i=(f.y%f.x),V=1y.1z(h/f.x);g.11(V).1A(\'a\').1B({\'1C-1D\':\'-\'+(i*V)+\'1E\'})};5(f.m)g.n(\'9-4-1e\');B g.n(\'9-4-1G\').1d(7(){$(3).4(\'1f\');$(3).4(\'G\')}).1b(7(){$(3).4(\'v\');$(3).4(\'F\')}).1h(7(){$(3).4(\'w\')});5(3.L)f.o=g;c.1i();c.1N(7(){$(3).4(\'w\')});g.6(\'4.r\',c.6(\'4.9\',g));f.C[f.C.K]=g[0];f.u[f.u.K]=c[0];f.q=d[a]=e;f.1P=b;c.6(\'4\',f);e.6(\'4\',f);g.6(\'4\',f);b.6(\'4\',d)});$(\'.4-T-13-S\').4(\'v\').D(\'4-T-13-S\');l 3};$.10($.p.4,{G:7(){8 a=3.6(\'4\');5(!a)l 3;5(!a.G)l 3;8 b=$(3).6(\'4.r\')||$(3.Z==\'X\'?3:s);5(a.G)a.G.H(b[0],[b.I(),$(\'a\',b.6(\'4.9\'))[0]])},F:7(){8 a=3.6(\'4\');5(!a)l 3;5(!a.F)l 3;8 b=$(3).6(\'4.r\')||$(3.Z==\'X\'?3:s);5(a.F)a.F.H(b[0],[b.I(),$(\'a\',b.6(\'4.9\'))[0]])},1f:7(){8 a=3.6(\'4\');5(!a)l 3;5(a.m)l;3.4(\'N\');3.1n().1o().Y(\'.q-\'+a.t).n(\'9-4-M\')},N:7(){8 a=3.6(\'4\');5(!a)l 3;5(a.m)l;a.q.1W().Y(\'.q-\'+a.t).D(\'9-4-1q\').D(\'9-4-M\')},v:7(){8 a=3.6(\'4\');5(!a)l 3;3.4(\'N\');5(a.o){a.o.6(\'4.r\').R(\'L\',\'L\');a.o.1n().1o().Y(\'.q-\'+a.t).n(\'9-4-1q\')}B $(a.u).1r(\'L\');a.A[a.m||a.1Y?\'1i\':\'1Z\']();3.20()[a.m?\'n\':\'D\'](\'9-4-1e\')},w:7(a){8 b=3.6(\'4\');5(!b)l 3;5(b.m)l;b.o=s;5(E a!=\'1s\'){5(E a==\'19\')l $(b.C[a]).4(\'w\');5(E a==\'1j\')$.W(b.C,7(){5($(3).6(\'4.r\').I()==a)$(3).4(\'w\')})}B b.o=3[0].Z==\'X\'?3.6(\'4.9\'):(3.22(\'.q-\'+b.t)?3:s);3.6(\'4\',b);3.4(\'v\');8 c=$(b.o?b.o.6(\'4.r\'):s);5(b.1g)b.1g.H(c[0],[c.I(),$(\'a\',b.o)[0]])},m:7(a,b){8 c=3.6(\'4\');5(!c)l 3;c.m=a||a==1s?z:P;5(b)$(c.u).R("Q","Q");B $(c.u).1r("Q");3.6(\'4\',c);3.4(\'v\')},24:7(){3.4(\'m\',z,z)},25:7(){3.4(\'m\',P,P)}});$.p.4.18={A:\'26 27\',15:\'\',x:0,1c:16};$(7(){$(\'r[28=1w].9\').4()})})(1t);',62,134,'|||this|rating|if|data|function|var|star||||||||||||return|readOnly|addClass|current|fn|rater|input|null|serial|inputs|draw|select|split|count|true|cancel|else|stars|removeClass|typeof|blur|focus|apply|val|arguments|length|checked|hover|drain|div|false|disabled|attr|drawn|to|id|spw|each|INPUT|filter|tagName|extend|width|class|be|title|cancelValue||className|options|number|append|mouseout|starWidth|mouseover|readonly|fill|callback|click|hide|string|metadata|applied|document|prevAll|andSelf|value|on|removeAttr|undefined|jQuery|BackgroundImageCache|not|radio|msie|Math|floor|find|css|margin|left|px|catch|live|meta|try|name|unnamed|replace|span|change|window|context|control|before|_|makeArray|form|half|children|body|required|show|siblings|slice|is|execCommand|disable|enable|Cancel|Rating|type|browser'.split('|'),0,{}))
================================================
FILE: extensions/community/languages/community-de.csv
================================================
Comment;Kommentar
Post Comment;Kommentar hinzufügen
Enter your Comment;Gib einen Kommentar ab
There are no discussions yet.;Es gibt noch keine Kommentare.
HISTORY_ACTIONTYPE_110;Kommentar hinzugefügt
HISTORY_ACTIONTYPE_111;DataWrapper benutzt
================================================
FILE: extensions/community/languages/community-en.csv
================================================
HISTORY_ACTIONTYPE_110;comment added
HISTORY_ACTIONTYPE_111;datawrapper used
================================================
FILE: extensions/community/rating.js
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
$(document).ready(function() {
var rating_disp = document.getElementsByName('rating');
var rating_in = document.getElementsByName('rating_input');
var rating_user = document.getElementsByName('rating_user');
var submitbutton = document.getElementsByName('submitbutton');
var tab0 = document.getElementById('change0');
var tab1 = document.getElementById('change1');
var tab2 = document.getElementById('change2');
var tab3 = document.getElementById('change3');
var tab4 = document.getElementById('change4');
var tab5 = document.getElementById('change5');
document.getElementById('rate_text').innerHTML = ' '+ratingValue +' '+'votes'+' ('+count+')';
if(count != '0'){
$(rating_disp).rating('select',rating) ;
}
$(submitbutton).click(function(){
if(getCheckedValue(rating_in) != '')
{
if(creator == '1')
{
newcount = parseInt(count);
ratingValuenew = (((parseFloat(ratingValue)) * parseInt(count)) - parseFloat(creatorNote+1) + parseFloat(getCheckedValue(rating_in)))/newcount;
}
else
{
newcount = parseInt(count)+1;
ratingValuenew = ((parseFloat(ratingValue) * parseInt(count)) + parseFloat(getCheckedValue(rating_in)))/newcount;
}
displayValue = Math.round((ratingValuenew * 2) -1);
$(rating_user).rating('readOnly',false);
$(rating_user).rating('select',getCheckedValue(rating_in));
$(rating_user).rating('readOnly',true);
$(rating_disp).rating('readOnly',false);
$(rating_disp).rating('select',displayValue);
$(rating_disp).rating('readOnly',true);
tab0.style.display = 'none';
tab1.style.display = 'none';
tab2.style.display = 'none';
tab3.style.display = '';
tab4.style.display = '';
tab5.style.display = '';
document.getElementById('rate_text').innerHTML = ' '+ Math.round(ratingValuenew*100)/100 +' '+'votes'+' ('+newcount+')';
}
});
$(rating_disp).rating('readOnly',true);
$(rating_in).rating('readOnly',false);
if(creator == 1){
$(rating_user).rating('readOnly',false);
$(rating_user).rating('select',creatorNote);
$(rating_user).rating('readOnly',true);
tab0.style.display = 'none';
tab1.style.display = 'none';
tab2.style.display = 'none';
tab3.style.display = '';
tab4.style.display = '';
tab5.style.display = '';
}
$('#changebutton').click(function(){
tab0.style.display = '';
tab1.style.display = '';
tab2.style.display = '';
tab3.style.display = 'none';
tab4.style.display = 'none';
tab5.style.display = 'none';
});
$('#ratingfield').mouseout(function(){
$('#submit').val(getCheckedValue(rating_in));
});
});
function getCheckedValue(radioObj) {
if(!radioObj)
return "";
var radioLength = radioObj.length;
if(radioLength == undefined)
if(radioObj.checked)
return radioObj.value;
else
return "";
for(var i = 0; i < radioLength; i++) {
if(radioObj[i].checked) {
return radioObj[i].value;
}
}
return "";
}
================================================
FILE: extensions/community/styles/community.css
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
.comment {
background-image: ;
}
================================================
FILE: extensions/community/templates/comment.phtml
================================================
';
// }
// });
$('#location_bar_input').result(function(e, data, formated) {
$(this).attr('value', data[1]);
});
}
/**
* Removes the location bar.
*/
function hideLocationBar()
{
$('#location_bar_container').hide();
$('a.location_bar').addClass('show');
}
/**
* Function that executes a URI search.
*/
function uriSearch(term, cb)
{
var searchUrl = urlBase + 'datagathering/search?q=' + term;
$.getJSON(searchUrl,
function(jsonData) {
cb(jsonData);
});
}
================================================
FILE: extensions/datagathering/default.ini
================================================
enabled = true
name = "Linked Data Gathering"
description = "a component and a wrapper to import linked data and expand local models."
author = "AKSW"
authorUrl = "http://aksw.org"
templates = "templates/"
languages = "languages/"
[events] ; for plugin
1 = onCreateMenu ; Menu entries
2 = onPropertiesAction ; Location bar menu entry
3 = onPreTabsContentAction ; Location bar
4 = onDeleteResources ; Sync
5 = onPreDeleteModel ; Sync
[private]
sync.enabled = false
;syncModelUri = "http://localhost/OntoWiki/Sync/"
;syncModelUri = "http://localhost/OntoWiki/Config/"
;syncModelFilename = "SyncSchema.rdf"
;syncHelperModelBase = "http://localhost/OntoWiki/Sync/Helper"
;properties.syncConfigClass = "http://ns.ontowiki.net/Sync/SyncConfig"
;properties.targetModel = "http://ns.ontowiki.net/Sync/targetModel"
;properties.syncResource = "http://ns.ontowiki.net/Sync/syncResource"
;properties.wrapperName = "http://ns.ontowiki.net/Sync/wrapperName"
;properties.syncQuery = "http://ns.ontowiki.net/Sync/syncQuery"
;properties.lastSyncDateTime = "http://ns.ontowiki.net/Sync/lastSyncDateTime"
;properties.lastSyncPayload = "http://ns.ontowiki.net/Sync/lastSyncPayload"
;properties.checkHasChanged = "http://ns.ontowiki.net/Sync/checkHasChanged"
;;; DatagatheringComponent
;fetch.allData = true ; If enabled, not only data with subject == resource URI is imported, but all returned data.
fetch.default.mode = "all" ; all (default), none
;fetch.default.exception[] = "http://www.w3.org/2000/01/rdf-schema#label"
fetch.preset.0.match = "http://dbpedia.org"
fetch.preset.0.mode = "none" ; all (default), none
fetch.preset.0.lang[] = "en"
fetch.preset.0.exception[] = "http://www.w3.org/2000/01/rdf-schema#label"
fetch.preset.0.exception[] = "http://xmlns.com/foaf/0.1/depiction"
fetch.preset.0.exception[] = "http://xmlns.com/foaf/0.1/name"
fetch.preset.0.exception[] = "http://xmlns.com/foaf/0.1/page"
fetch.preset.0.exception[] = "http://xmlns.com/foaf/0.1/homepage"
fetch.preset.0.exception[] = "http://dbpedia.org/ontology/birthDate"
fetch.preset.0.exception[] = "http://dbpedia.org/ontology/birthPlace"
fetch.preset.0.exception[] = "http://dbpedia.org/ontology/abstract"
fetch.preset.0.exception[] = "http://www.w3.org/2003/01/geo/wgs84_pos#lat"
fetch.preset.0.exception[] = "http://www.w3.org/2003/01/geo/wgs84_pos#long"
; have a look at http://de2.php.net/manual/en/function.preg-replace.php
; for documantion about pattern and replace options
rewrite.lsid.pattern = "/^(urn:lsid:.+)$/"
rewrite.lsid.replacement = "http://lsid.tdwg.org/$1"
rewrite.go.pattern = "/^http:\/\/www.geneontology.org\/go#GO:([0-9]+)$/"
rewrite.go.replacement = "http://go.ontowiki.de/$1"
;;; LinkedDataWrapper
handle.mode = "all" ; all: handle all http uris, none: handle no uris
;handle.exception[] = "http://dbpedia.org" ; exceptions for handle mode, e.g http://dbpedia.org*
;;; RdfaWrapper
ignore[] = 'http://www.w3.org/1999/xhtml/vocab#stylesheet'
ignore[] = 'http://www.w3.org/1999/xhtml/vocab#alternate'
ignore[] = 'http://poshrdf.org/ns/mf#nofollow'
defaultClass = 'http://xmlns.com/foaf/0.1/Document'
================================================
FILE: extensions/datagathering/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :datagathering .
:datagathering a doap:Project ;
doap:name "datagathering" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Linked Data Gathering" ;
doap:description "a component and a wrapper to import linked data and expand local models." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:templates "templates/" ;
owconfig:languages "languages/" ;
owconfig:pluginEvent event:onCreateMenu ;
owconfig:pluginEvent event:onPropertiesAction ;
owconfig:pluginEvent event:onPreTabsContentAction ;
owconfig:pluginEvent event:onDeleteResources ;
owconfig:pluginEvent event:onPreDeleteModel ;
owconfig:config [
a owconfig:Config;
owconfig:id "sync";
owconfig:enabled "false"^^xsd:boolean
];
owconfig:config [
a owconfig:Config;
owconfig:id "fetch";
owconfig:config [
a owconfig:Config;
owconfig:id "default";
:mode "all"
];
owconfig:config [
a owconfig:Config;
owconfig:id "preset";
owconfig:config [
a owconfig:Config;
owconfig:id "0";
:match ;
:mode "none" ;
:lang "en" ;
:exception ;
:exception ;
:exception ;
:exception ;
:exception ;
:exception ;
:exception ;
:exception ;
:exception ;
:exception
]
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "rewrite";
owconfig:config [
a owconfig:Config;
owconfig:id "lsid";
:pattern "/^(urn:lsid:.+)$/" ;
:replacement
];
owconfig:config [
a owconfig:Config;
owconfig:id "go";
:pattern "/^http:\\/\\/www.geneontology.org\\/go#GO:([0-9]+)$/" ;
:replacement
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "handle";
:mode "all"
];
:ignore ;
:ignore ;
:ignore ;
:defaultClass .
:datagathering doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/datagathering/languages/datagathering-de.csv
================================================
Sync Data with %1$s;Daten mit %1$s synchronisieren
Import Data with %1$s;Daten mit %1$s importieren
Configure Sync with %1$s;Synchronisation mit %1$s konfigurieren
This Resource is configured for Sync;Diese Ressource ist für eine Synchronisation konfiguriert
This Resource has changed since last sync;Diese Ressource wurde seit der letzten Synchronisation aktualisiert
Last Sync;Letze Synchronisation
Last Modified;Zuletzt modifiziert
Sync;Synchronisieren
View Resource;Ressource anzeigen
Show/Hide Location Bar;Adressleiste zeigen/verstecken
Local Search;Lokale Suche
Expanded QNames;Expandierte qualifizierte Bezeichner
Sindice Search;Sindice Suche
Generated URI;Automatisch generierte URI
Data was found for the given URI. %1$d statements were added.;Daten wurden für die gegebene URI gefunden und es wurden %1$d Statements hinzugefügt.
Data was found for the given URI but no statements were added.;Es wurden Daten für die gegebene URI gefunden, aber es wurden keine Statements hinzugefügt.
No data returned for the given URI by wrapper.;Keine Daten für die gegebene URI vom Wrapper gefunden.
No data was imported;Es wurden keine Daten importiert
No existing sync configuration. Create one now by clicking the Save button.;Es existiert bisher keine Konfiguration. Sie können nun eine Konfiguration erstellen, durch klicken auf Speichern.
Sync Configuration;Synchronisations-Konfiguration
Model URI;Modell-URI
Wrapper Name;Wrapper-Name
Resource URI;Ressource URI
Check for Updates;Auf Aktualisierungen prüfen
Sync Query;Sync-Anfrage
HISTORY_ACTIONTYPE_1010;Daten importiert
HISTORY_ACTIONTYPE_1020;Ressource synchonisiert
================================================
FILE: extensions/datagathering/languages/datagathering-en.csv
================================================
Sync Data with %1$s;Sync Data with %1$s
Import Data with %1$s;Import Data with %1$s
Configure Sync with %1$s;Configure Sync with %1$s
This Resource is configured for Sync;This Resource is configured for Sync
This Resource has changed since last sync;This Resource has changed since last sync
Last Sync;Last Sync
Last Modified;Last Modified
Sync;Sync
View Resource;View Resource
Show/Hide Location Bar;Show/Hide Location Bar
Local Search;Local Search
Expanded QNames;Expanded QNames
Sindice Search;Sindice Search
Generated URI;Generated URI
Data was found for the given URI. %1$d statements were added.;Data was found for the given URI. %1$d statements were added.
Data was found for the given URI but no statements were added.;Data was found for the given URI but no statements were added.
No data returned for the given URI by wrapper.;No data returned for the given URI by wrapper.
No data was imported;No data was imported
No existing sync configuration. Create one now by clicking the Save button.;No existing sync configuration. Create one now by clicking the Save button.
Sync Configuration;Sync Configuration
Model URI;Model URI
Wrapper Name;Wrapper Name
Resource URI;Resource URI
Check for Updates;Check for Updates
Sync Query;Sync Query
HISTORY_ACTIONTYPE_1010;data import
HISTORY_ACTIONTYPE_1020;resource synced
================================================
FILE: extensions/datagathering/scripts/jquery.autocomplete.js
================================================
/*
* Autocomplete - jQuery plugin 1.0.2
*
* Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
*
*/
;(function($) {
$.fn.extend({
_autocomplete: function(urlOrData, options) {
var isUrl = (typeof urlOrData == "string" || typeof urlOrData == "function");
options = $.extend({}, $.Autocompleter.defaults, {
url: isUrl ? urlOrData : null,
data: isUrl ? null : urlOrData,
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
max: options && !options.scroll ? 10 : 150
}, options);
// if highlight is set to false, replace it with a do-nothing function
options.highlight = options.highlight || function(value) { return value; };
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
options.formatMatch = options.formatMatch || options.formatItem;
return this.each(function() {
new $.Autocompleter(this, options);
});
},
result: function(handler) {
return this.bind("result", handler);
},
search: function(handler) {
return this.trigger("search", [handler]);
},
flushCache: function() {
return this.trigger("flushCache");
},
setOptions: function(options){
return this.trigger("setOptions", [options]);
},
unautocomplete: function() {
return this.trigger("unautocomplete");
}
});
$.Autocompleter = function(input, options) {
var KEY = {
UP: 38,
DOWN: 40,
DEL: 46,
TAB: 9,
RETURN: 13,
ESC: 27,
COMMA: 188,
PAGEUP: 33,
PAGEDOWN: 34,
BACKSPACE: 8
};
// Create $ object for input element
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
var timeout;
var previousValue = "";
var cache = $.Autocompleter.Cache(options);
var hasFocus = 0;
var lastKeyPressCode;
var config = {
mouseDownOnSelect: false
};
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
var blockSubmit;
// prevent form submit in opera when selecting with return key
$.browser.opera && $(input.form).bind("submit.autocomplete", function() {
if (blockSubmit) {
blockSubmit = false;
return false;
}
});
// only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
$input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
// track last key pressed
lastKeyPressCode = event.keyCode;
switch(event.keyCode) {
case KEY.UP:
event.preventDefault();
if ( select.visible() ) {
select.prev();
} else {
onChange(0, true);
}
break;
case KEY.DOWN:
event.preventDefault();
if ( select.visible() ) {
select.next();
} else {
onChange(0, true);
}
break;
case KEY.PAGEUP:
event.preventDefault();
if ( select.visible() ) {
select.pageUp();
} else {
onChange(0, true);
}
break;
case KEY.PAGEDOWN:
event.preventDefault();
if ( select.visible() ) {
select.pageDown();
} else {
onChange(0, true);
}
break;
// matches also semicolon
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
case KEY.TAB:
case KEY.RETURN:
if( selectCurrent() ) {
// stop default to prevent a form submit, Opera needs special handling
event.preventDefault();
blockSubmit = true;
return false;
}
break;
case KEY.ESC:
select.hide();
break;
default:
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break;
}
}).focus(function(){
// track whether the field has focus, we shouldn't process any
// results if the field no longer has focus
hasFocus++;
}).blur(function() {
hasFocus = 0;
if (!config.mouseDownOnSelect) {
hideResults();
}
}).click(function() {
// show select when clicking in a focused field
if ( hasFocus++ > 1 && !select.visible() ) {
onChange(0, true);
}
}).bind("search", function() {
// TODO why not just specifying both arguments?
var fn = (arguments.length > 1) ? arguments[1] : null;
function findValueCallback(q, data) {
var result;
if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
}
}
if( typeof fn == "function" ) fn(result);
else $input.trigger("result", result && [result.data, result.value]);
}
$.each(trimWords($input.val()), function(i, value) {
request(value, findValueCallback, findValueCallback);
});
}).bind("flushCache", function() {
cache.flush();
}).bind("setOptions", function() {
$.extend(options, arguments[1]);
// if we've updated the data, repopulate
if ( "data" in arguments[1] )
cache.populate();
}).bind("unautocomplete", function() {
select.unbind();
$input.unbind();
$(input.form).unbind(".autocomplete");
});
function selectCurrent() {
var selected = select.selected();
if( !selected )
return false;
var v = selected.result;
previousValue = v;
if ( options.multiple ) {
var words = trimWords($input.val());
if ( words.length > 1 ) {
v = words.slice(0, words.length - 1).join( options.multipleSeparator ) + options.multipleSeparator + v;
}
v += options.multipleSeparator;
}
$input.val(v);
hideResultsNow();
$input.trigger("result", [selected.data, selected.value]);
return true;
}
function onChange(crap, skipPrevCheck) {
if( lastKeyPressCode == KEY.DEL ) {
select.hide();
return;
}
var currentValue = $input.val();
if ( !skipPrevCheck && currentValue == previousValue )
return;
previousValue = currentValue;
currentValue = lastWord(currentValue);
if ( currentValue.length >= options.minChars) {
$input.addClass(options.loadingClass);
if (!options.matchCase)
currentValue = currentValue.toLowerCase();
request(currentValue, receiveData, hideResultsNow);
} else {
stopLoading();
select.hide();
}
};
function trimWords(value) {
if ( !value ) {
return [""];
}
var words = value.split( options.multipleSeparator );
var result = [];
$.each(words, function(i, value) {
if ( $.trim(value) )
result[i] = $.trim(value);
});
return result;
}
function lastWord(value) {
if ( !options.multiple )
return value;
var words = trimWords(value);
return words[words.length - 1];
}
// fills in the input box w/the first match (assumed to be the best match)
// q: the term entered
// sValue: the first matching result
function autoFill(q, sValue){
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
// if the last user key pressed was backspace, don't autofill
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
// select the portion of the value not typed by the user (so the next character will erase)
$.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
}
};
function hideResults() {
clearTimeout(timeout);
timeout = setTimeout(hideResultsNow, 200);
};
function hideResultsNow() {
var wasVisible = select.visible();
select.hide();
clearTimeout(timeout);
stopLoading();
if (options.mustMatch) {
// call search and run callback
$input.search(
function (result){
// if no value found, clear the input box
if( !result ) {
if (options.multiple) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
else
$input.val( "" );
}
}
);
}
if (wasVisible)
// position cursor at end of input field
$.Autocompleter.Selection(input, input.value.length, input.value.length);
};
function receiveData(q, data) {
if ( data && data.length && hasFocus ) {
stopLoading();
select.display(data, q);
autoFill(q, data[0].value);
select.show();
} else {
hideResultsNow();
}
};
function request(term, success, failure) {
if (!options.matchCase)
term = term.toLowerCase();
var data = cache.load(term);
// recieve the cached data
if (data && data.length) {
success(term, data);
// if an AJAX url has been supplied, try loading the data now
} else if( (typeof options.url == "string") && (options.url.length > 0) ){
var extraParams = {
timestamp: +new Date()
};
$.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param;
});
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
}
});
} else if (typeof options.url == "function") {
options.url(lastWord(term), function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
});
} else {
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
select.emptyList();
failure(term);
}
};
function parse(data) {
var parsed = [];
var rows = data.split("\n");
for (var i=0; i < rows.length; i++) {
var row = $.trim(rows[i]);
if (row) {
row = row.split("|");
parsed[parsed.length] = {
data: row,
value: row[0],
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
};
}
}
return parsed;
};
function stopLoading() {
$input.removeClass(options.loadingClass);
};
};
$.Autocompleter.defaults = {
inputClass: "ac_input",
resultsClass: "ac_results",
loadingClass: "ac_loading",
minChars: 1,
delay: 400,
matchCase: false,
matchSubset: true,
matchContains: false,
cacheLength: 10,
max: 100,
mustMatch: false,
extraParams: {},
selectFirst: true,
formatItem: function(row) { return row[0]; },
formatMatch: null,
autoFill: false,
width: 0,
multiple: false,
multipleSeparator: ", ",
highlight: function(value, term) {
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1");
},
scroll: true,
scrollHeight: 180
};
$.Autocompleter.Cache = function(options) {
var data = {};
var length = 0;
function matchSubset(s, sub) {
if (!options.matchCase)
s = s.toLowerCase();
var i = s.indexOf(sub);
if (i == -1) return false;
return i == 0 || options.matchContains;
};
function add(q, value) {
if (length > options.cacheLength){
flush();
}
if (!data[q]){
length++;
}
data[q] = value;
}
function populate(){
if( !options.data ) return false;
// track the matches
var stMatchSets = {},
nullData = 0;
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
if( !options.url ) options.cacheLength = 1;
// track all options for minChars = 0
stMatchSets[""] = [];
// loop through the array and create a lookup structure
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
var rawValue = options.data[i];
// if rawValue is a string, make an array otherwise just reference the array
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
var value = options.formatMatch(rawValue, i+1, options.data.length);
if ( value === false )
continue;
var firstChar = value.charAt(0).toLowerCase();
// if no lookup array for this character exists, look it up now
if( !stMatchSets[firstChar] )
stMatchSets[firstChar] = [];
// if the match is a string
var row = {
value: value,
data: rawValue,
result: options.formatResult && options.formatResult(rawValue) || value
};
// push the current match into the set list
stMatchSets[firstChar].push(row);
// keep track of minChars zero items
if ( nullData++ < options.max ) {
stMatchSets[""].push(row);
}
};
// add the data items to the cache
$.each(stMatchSets, function(i, value) {
// increase the cache size
options.cacheLength++;
// add to the cache
add(i, value);
});
}
// populate any existing data
setTimeout(populate, 25);
function flush(){
data = {};
length = 0;
}
return {
flush: flush,
add: add,
populate: populate,
load: function(q) {
if (!options.cacheLength || !length)
return null;
/*
* if dealing w/local data and matchContains than we must make sure
* to loop through all the data collections looking for matches
*/
if( !options.url && options.matchContains ){
// track all matches
var csub = [];
// loop through all the data grids for matches
for( var k in data ){
// don't search through the stMatchSets[""] (minChars: 0) cache
// this prevents duplicates
if( k.length > 0 ){
var c = data[k];
$.each(c, function(i, x) {
// if we've got a match, add it to the array
if (matchSubset(x.value, q)) {
csub.push(x);
}
});
}
}
return csub;
} else
// if the exact item exists, use it
if (data[q]){
return data[q];
} else
if (options.matchSubset) {
for (var i = q.length - 1; i >= options.minChars; i--) {
var c = data[q.substr(0, i)];
if (c) {
var csub = [];
$.each(c, function(i, x) {
if (matchSubset(x.value, q)) {
csub[csub.length] = x;
}
});
return csub;
}
}
}
return null;
}
};
};
$.Autocompleter.Select = function (options, input, select, config) {
var CLASSES = {
ACTIVE: "ac_over"
};
var listItems,
active = -1,
data,
term = "",
needsInit = true,
element,
list;
// Create results
function init() {
if (!needsInit)
return;
element = $("")
.hide()
.addClass(options.resultsClass)
.css("position", "absolute")
.appendTo(document.body);
list = $("
").appendTo(element).mouseover( function(event) {
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
$(target(event)).addClass(CLASSES.ACTIVE);
}
}).click(function(event) {
$(target(event)).addClass(CLASSES.ACTIVE);
select();
// TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
input.focus();
return false;
}).mousedown(function() {
config.mouseDownOnSelect = true;
}).mouseup(function() {
config.mouseDownOnSelect = false;
});
if( options.width > 0 )
element.css("width", options.width);
needsInit = false;
}
function target(event) {
var element = event.target;
while(element && element.tagName != "LI")
element = element.parentNode;
// more fun with IE, sometimes event.target is empty, just ignore it then
if(!element)
return [];
return element;
}
function moveSelect(step) {
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
movePosition(step);
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
if(options.scroll) {
var offset = 0;
listItems.slice(0, active).each(function() {
offset += this.offsetHeight;
});
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
} else if(offset < list.scrollTop()) {
list.scrollTop(offset);
}
}
};
function movePosition(step) {
active += step;
if (active < 0) {
active = listItems.size() - 1;
} else if (active >= listItems.size()) {
active = 0;
}
}
function limitNumberOfItems(available) {
return options.max && options.max < available
? options.max
: available;
}
function fillList() {
list.empty();
var max = limitNumberOfItems(data.length);
for (var i=0; i < max; i++) {
if (!data[i])
continue;
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
if ( formatted === false )
continue;
var li = $("").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
$.data(li, "ac_data", data[i]);
}
listItems = list.find("li");
if ( options.selectFirst ) {
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
active = 0;
}
// apply bgiframe if available
if ( $.fn.bgiframe )
list.bgiframe();
}
return {
display: function(d, q) {
init();
data = d;
term = q;
fillList();
},
next: function() {
moveSelect(1);
},
prev: function() {
moveSelect(-1);
},
pageUp: function() {
if (active != 0 && active - 8 < 0) {
moveSelect( -active );
} else {
moveSelect(-8);
}
},
pageDown: function() {
if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
moveSelect( listItems.size() - 1 - active );
} else {
moveSelect(8);
}
},
hide: function() {
element && element.hide();
listItems && listItems.removeClass(CLASSES.ACTIVE);
active = -1;
},
visible : function() {
return element && element.is(":visible");
},
current: function() {
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
},
show: function() {
var offset = $(input).offset();
element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
top: offset.top + input.offsetHeight,
left: offset.left
}).show();
if(options.scroll) {
list.scrollTop(0);
list.css({
maxHeight: options.scrollHeight,
overflow: 'auto'
});
if($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
var listHeight = 0;
listItems.each(function() {
listHeight += this.offsetHeight;
});
var scrollbarsVisible = listHeight > options.scrollHeight;
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
if (!scrollbarsVisible) {
// IE doesn't recalculate width when scrollbar disappears
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
}
}
}
},
selected: function() {
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
return selected && selected.length && $.data(selected[0], "ac_data");
},
emptyList: function (){
list && list.empty();
},
unbind: function() {
element && element.remove();
}
};
};
$.Autocompleter.Selection = function(field, start, end) {
if( field.createTextRange ){
var selRange = field.createTextRange();
selRange.collapse(true);
selRange.moveStart("character", start);
selRange.moveEnd("character", end);
selRange.select();
} else if( field.setSelectionRange ){
field.setSelectionRange(start, end);
} else {
if( field.selectionStart ){
field.selectionStart = start;
field.selectionEnd = end;
}
}
field.focus();
};
})(jQuery);
================================================
FILE: extensions/datagathering/templates/datagathering/config.phtml
================================================
errorFlag) || $this->errorFlag === false): ?>
================================================
FILE: extensions/datagathering/tests/DatagatheringControllerTest.php
================================================
_extensionName = 'datagathering';
$this->setUpExtensionUnitTest();
}
public function testImportActionRequestTypeNotGetBadRequest()
{
$this->dispatch('/datagathering/import');
$this->assertController('error');
$this->assertAction('error');
@$this->assertResponseCode(400);
}
public function testImportActionNoParamsBadRequest()
{
$this->dispatch('/datagathering/import');
$this->assertController('error');
$this->assertAction('error');
@$this->assertResponseCode(400);
}
public function testImportActionInvalidWrapperParamBadRequest()
{
$this->request->setQuery(
array(
'wrapper' => 'anInvalidWrapperName123456789ThisShouldNeverExist'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('error');
$this->assertAction('error');
@$this->assertResponseCode(400);
}
public function testImportActionModelNotEditableForbidden()
{
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'deny');
$this->request->setQuery(
array(
'uri' => 'http://example.org/testResource1',
'm' => 'http://example.org/testModel1'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('error');
$this->assertAction('error');
@$this->assertResponseCode(403);
}
public function testImportActionWrapperResultFalse()
{
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'grant');
$this->request->setQuery(
array(
'uri' => 'http://example.org/testResource1',
'm' => 'http://example.org/testModel1',
'wrapper' => 'Erfurt_Wrapper_Test'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('datagathering');
$this->assertAction('import');
@$this->assertResponseCode(200);
$result = json_decode($this->_response->getBody(), true);
$this->assertArrayHasKey('code', $result);
$this->assertFalse($result['code']);
$this->assertArrayHasKey('message', $result);
$this->assertNotEmpty($result['message']);
}
public function testImportActionWrapperResultEmptyArray()
{
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'grant');
Erfurt_Wrapper_Test::$runResult = array();
$this->request->setQuery(
array(
'uri' => 'http://example.org/testResource1',
'm' => 'http://example.org/testModel1',
'wrapper' => 'Erfurt_Wrapper_Test'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('datagathering');
$this->assertAction('import');
@$this->assertResponseCode(200);
$result = json_decode($this->_response->getBody(), true);
$this->assertArrayHasKey('code', $result);
$this->assertFalse($result['code']);
$this->assertArrayHasKey('message', $result);
$this->assertNotEmpty($result['message']);
}
public function testImportActionWrapperResultArrayNoAdd()
{
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'grant');
Erfurt_Wrapper_Test::$runResult = array('status_codes' => array());
$this->request->setQuery(
array(
'uri' => 'http://example.org/testResource1',
'm' => 'http://example.org/testModel1',
'wrapper' => 'Erfurt_Wrapper_Test'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('datagathering');
$this->assertAction('import');
@$this->assertResponseCode(200);
$result = json_decode($this->_response->getBody(), true);
$this->assertArrayHasKey('code', $result);
$this->assertFalse($result['code']);
$this->assertArrayHasKey('message', $result);
$this->assertNotEmpty($result['message']);
}
public function testImportActionWrapperResultArrayWithAddButNothingAdded()
{
Erfurt_App::getInstance()->getVersioning()->enableVersioning(false);
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'grant');
Erfurt_Wrapper_Test::$runResult = array(
'status_codes' => array(Erfurt_Wrapper::RESULT_HAS_ADD),
'add' => array()
);
$this->request->setQuery(
array(
'uri' => 'http://example.org/testResource1',
'm' => 'http://example.org/testModel1',
'wrapper' => 'Erfurt_Wrapper_Test'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('datagathering');
$this->assertAction('import');
@$this->assertResponseCode(200);
$result = json_decode($this->_response->getBody(), true);
$this->assertArrayHasKey('code', $result);
$this->assertFalse($result['code']);
$this->assertArrayHasKey('message', $result);
$this->assertNotEmpty($result['message']);
}
public function testImportActionWrapperResultArrayWithAdd()
{
Erfurt_App::getInstance()->getVersioning()->enableVersioning(false);
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'grant');
$this->_storeAdapter->addCountResult(0);
$this->_storeAdapter->addCountResult(2);
$add = array(
'http://example.org/testResource1' => array(
'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array(array(
'type' => 'uri',
'value' => 'http://xmlns.com/foaf/0.1/Person'
)),
'http://xmlns.com/foaf/0.1/nick' => array(array(
'type' => 'literal',
'value' => 'testResource1'
))
)
);
Erfurt_Wrapper_Test::$runResult = array(
'status_codes' => array(Erfurt_Wrapper::RESULT_HAS_ADD),
'add' => $add
);
$this->request->setQuery(
array(
'uri' => 'http://example.org/testResource1',
'm' => 'http://example.org/testModel1',
'wrapper' => 'Erfurt_Wrapper_Test'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('datagathering');
$this->assertAction('import');
@$this->assertResponseCode(200);
$result = json_decode($this->_response->getBody(), true);
$this->assertArrayHasKey('code', $result);
$this->assertTrue($result['code']);
$this->assertArrayHasKey('message', $result);
$this->assertNotEmpty($result['message']);
$this->assertEquals($add, $this->_storeAdapter->getStatementsForGraph('http://example.org/testModel1'));
}
public function testImportActionWrapperResultArrayWithAddMatchingPreset()
{
Erfurt_App::getInstance()->getVersioning()->enableVersioning(false);
$this->_storeAdapter->createModel('http://example.org/testModel1');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'view', 'grant');
$this->_ac->setUserModelRight('http://example.org/testModel1', 'edit', 'grant');
$this->_storeAdapter->addCountResult(0);
$this->_storeAdapter->addCountResult(2);
$add = array(
'http://dbpedia.org/resource/Leipzig' => array(
'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array(array(
'type' => 'uri',
'value' => 'http://xmlns.com/foaf/0.1/Person'
)),
'http://xmlns.com/foaf/0.1/nick' => array(array(
'type' => 'literal',
'value' => 'testResource1'
))
)
);
Erfurt_Wrapper_Test::$runResult = array(
'status_codes' => array(Erfurt_Wrapper::RESULT_HAS_ADD),
'add' => $add
);
$this->request->setQuery(
array(
'uri' => 'http://dbpedia.org/resource/Leipzig',
'm' => 'http://example.org/testModel1',
'wrapper' => 'Erfurt_Wrapper_Test'
)
);
$this->dispatch('/datagathering/import');
$this->assertController('datagathering');
$this->assertAction('import');
@$this->assertResponseCode(200);
$result = json_decode($this->_response->getBody(), true);
$this->assertArrayHasKey('code', $result);
$this->assertTrue($result['code']);
$this->assertArrayHasKey('message', $result);
$this->assertNotEmpty($result['message']);
$this->assertEquals(array(), $this->_storeAdapter->getStatementsForGraph('http://example.org/testModel1'));
}
}
================================================
FILE: extensions/defaultmodel/DefaultmodelPlugin.php
================================================
get("m")) {
return;
}
$config = $this->_privateConfig->toArray();
$efApp = Erfurt_App::getInstance();
// disable model box if config value is true and modelmanangement isn't allowed
if ($config['modelsHide'] && !$efApp->getAc()->isActionAllowed($config['modelsExclusiveRight'])) {
$registry = OntoWiki_Module_Registry::getInstance();
$registry->disableModule('modellist', 'main.sidewindow');
}
//only do this once (so if the model is changed later, this plugin will not prevent it)
if ($config['setOnce'] && isset($_SESSION['defaultModelHasBeenSet']) && $_SESSION['defaultModelHasBeenSet']) {
return;
}
$_SESSION['defaultModelHasBeenSet'] = true;
require_once 'OntoWiki/Module/Registry.php';
$owApp = OntoWiki::getInstance();
$efStore = $efApp->getStore();
$availableModels = $efStore->getAvailableModels();
if (array_key_exists('modelUri', $config)
&& array_key_exists($config['modelUri'], $availableModels)
) {
$modelUri = $config['modelUri'];
} elseif (count($availableModels) === 1) {
$modelUri = current(array_keys($availableModels));
} else {
$modelUri = false;
}
// set default model if it could be determined
if ($modelUri && !$efApp->getAc()->isActionAllowed($config['modelsExclusiveRight'])) {
if (!($owApp->selectedModel && ($modelUri == $owApp->selectedModel->getModelUri()))) {
$owApp->selectedModel = $efStore->getModel($modelUri);
return;
}
if ($config['setSelectedResource']) {
$owApp->selectedResource = $modelUri;
}
}
}
}
================================================
FILE: extensions/defaultmodel/default.ini
================================================
enabled = false
name = "Default Model"
description = "Plugin to select default model if only one available or always"
author = "Christoph Rieß"
; url =
[events]
1 = onAfterInitController
[private]
; which model should be selected by default
modelUri = "http://showcase.ontowiki.net/"
; set to true if you want to set the model only on the first session use
; this implies that you can switch to another model thereafter
; setting it to false, means that each request sets the model, thus forcing it permanently
setOnce = true
; set to true if you do not want to have a visible Knowledge Base module (but "modelsExclusiveRight", force it to appear)
modelsHide = true
; however, the module is always shown if the user has the following
; action-based access right (because Admins need this module)
modelsExclusiveRight = "ModelManagement"
; after selecting model the selectedResource will be set to the modelUri
; (dont use it, it will crash lists)
setSelectedResource = false
================================================
FILE: extensions/defaultmodel/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :defaultmodel .
:defaultmodel a doap:Project ;
doap:name "defaultmodel" ;
owconfig:privateNamespace ;
owconfig:enabled "false"^^xsd:boolean ;
rdfs:label "Default Model" ;
doap:description "Plugin to select default model if only one available or always" ;
owconfig:authorLabel "Christoph Rieß" ;
owconfig:pluginEvent event:onAfterInitController ;
:modelUri ;
:setOnce "true"^^xsd:boolean ;
:modelsHide "true"^^xsd:boolean ;
:modelsExclusiveRight "ModelManagement" ;
:setSelectedResource "false"^^xsd:boolean ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/exconf/Archive.php
================================================
options = array(
'basedir' => ".",
'name' => $name,
'prepend' => "",
'inmemory' => 0,
'overwrite' => 0,
'recurse' => 1,
'storepaths' => 1,
'followlinks' => 0,
'level' => 3,
'method' => 1,
'sfx' => "",
'type' => "",
'comment' => ""
);
$this->files = array();
$this->exclude = array();
$this->storeonly = array();
$this->error = array();
}
function set_options($options)
{
foreach ($options as $key => $value) {
$this->options[$key] = $value;
}
if (!empty ($this->options['basedir'])) {
$this->options['basedir'] = str_replace("\\", "/", $this->options['basedir']);
$this->options['basedir'] = preg_replace("/\/+/", "/", $this->options['basedir']);
$this->options['basedir'] = preg_replace("/\/$/", "", $this->options['basedir']);
}
if (!empty ($this->options['name'])) {
$this->options['name'] = str_replace("\\", "/", $this->options['name']);
$this->options['name'] = preg_replace("/\/+/", "/", $this->options['name']);
}
if (!empty ($this->options['prepend'])) {
$this->options['prepend'] = str_replace("\\", "/", $this->options['prepend']);
$this->options['prepend'] = preg_replace("/^(\.*\/+)+/", "", $this->options['prepend']);
$this->options['prepend'] = preg_replace("/\/+/", "/", $this->options['prepend']);
$this->options['prepend'] = preg_replace("/\/$/", "", $this->options['prepend']) . "/";
}
}
function create_archive()
{
$this->make_list();
if ($this->options['inmemory'] == 0) {
$pwd = getcwd();
chdir($this->options['basedir']);
if ($this->options['overwrite'] == 0
&& file_exists(
$this->options['name'] . (
$this->options['type'] == "gzip" || $this->options['type'] == "bzip" ? ".tmp" : "")
)
) {
$this->error[] = "File {$this->options['name']} already exists.";
chdir($pwd);
return 0;
} else {
if ($this->archive = @fopen(
$this->options['name'] . (
$this->options['type'] == "gzip" || $this->options['type'] == "bzip" ? ".tmp" : ""), "wb+"
)
) {
chdir($pwd);
} else {
$this->error[] = "Could not open {$this->options['name']} for writing.";
chdir($pwd);
return 0;
}
}
} else {
$this->archive = "";
}
switch ($this->options['type']) {
case "zip":
if (!$this->create_zip()) {
$this->error[] = "Could not create zip file.";
return 0;
}
break;
case "bzip":
if (!$this->create_tar()) {
$this->error[] = "Could not create tar file.";
return 0;
}
if (!$this->create_bzip()) {
$this->error[] = "Could not create bzip2 file.";
return 0;
}
break;
case "gzip":
if (!$this->create_tar()) {
$this->error[] = "Could not create tar file.";
return 0;
}
if (!$this->create_gzip()) {
$this->error[] = "Could not create gzip file.";
return 0;
}
break;
case "tar":
if (!$this->create_tar()) {
$this->error[] = "Could not create tar file.";
return 0;
}
}
if ($this->options['inmemory'] == 0) {
fclose($this->archive);
if ($this->options['type'] == "gzip" || $this->options['type'] == "bzip") {
unlink($this->options['basedir'] . "/" . $this->options['name'] . ".tmp");
}
}
}
function add_data($data)
{
if ($this->options['inmemory'] == 0) {
fwrite($this->archive, $data);
} else {
$this->archive .= $data;
}
}
function make_list()
{
if (!empty ($this->exclude)) {
foreach ($this->files as $key => $value) {
foreach ($this->exclude as $current) {
if ($value['name'] == $current['name']) {
unset ($this->files[$key]);
}
}
}
}
if (!empty ($this->storeonly)) {
foreach ($this->files as $key => $value) {
foreach ($this->storeonly as $current) {
if ($value['name'] == $current['name']) {
$this->files[$key]['method'] = 0;
}
}
}
}
unset ($this->exclude, $this->storeonly);
}
function add_files($list)
{
$temp = $this->list_files($list);
foreach ($temp as $current) {
$this->files[] = $current;
}
}
function exclude_files($list)
{
$temp = $this->list_files($list);
foreach ($temp as $current) {
$this->exclude[] = $current;
}
}
function store_files($list)
{
$temp = $this->list_files($list);
foreach ($temp as $current) {
$this->storeonly[] = $current;
}
}
function list_files($list)
{
if (!is_array($list)) {
$temp = $list;
$list = array($temp);
unset ($temp);
}
$files = array();
$pwd = getcwd();
chdir($this->options['basedir']);
foreach ($list as $current) {
$current = str_replace("\\", "/", $current);
$current = preg_replace("/\/+/", "/", $current);
$current = preg_replace("/\/$/", "", $current);
if (strstr($current, "*")) {
$regex = preg_replace("/([\\\^\$\.\[\]\|\(\)\?\+\{\}\/])/", "\\\\\\1", $current);
$regex = str_replace("*", ".*", $regex);
$dir = strstr($current, "/") ? substr($current, 0, strrpos($current, "/")) : ".";
$temp = $this->parse_dir($dir);
foreach ($temp as $current2) {
if (preg_match("/^{$regex}$/i", $current2['name'])) {
$files[] = $current2;
}
}
unset ($regex, $dir, $temp, $current);
} else {
if (@is_dir($current)) {
$temp = $this->parse_dir($current);
foreach ($temp as $file) {
$files[] = $file;
}
unset ($temp, $file);
} else {
if (@file_exists($current)) {
$files[] = array('name' => $current, 'name2' => $this->options['prepend'] .
preg_replace(
"/(\.+\/+)+/", "", ($this->options['storepaths'] == 0 && strstr($current, "/")) ?
substr($current, strrpos($current, "/") + 1) : $current
),
'type' => @is_link($current) && $this->options['followlinks'] == 0 ? 2 : 0,
'ext' => substr($current, strrpos($current, ".")), 'stat' => stat($current));
}
}
}
}
chdir($pwd);
unset ($current, $pwd);
usort($files, array("archive", "sort_files"));
return $files;
}
function parse_dir($dirname)
{
if ($this->options['storepaths'] == 1 && !preg_match("/^(\.+\/*)+$/", $dirname)) {
$files = array(array('name' => $dirname, 'name2' => $this->options['prepend'] .
preg_replace(
"/(\.+\/+)+/", "", ($this->options['storepaths'] == 0 && strstr($dirname, "/")) ?
substr($dirname, strrpos($dirname, "/") + 1) : $dirname
), 'type' => 5, 'stat' => stat($dirname)));
} else {
$files = array();
}
$dir = @opendir($dirname);
while ($file = @readdir($dir)) {
$fullname = $dirname . "/" . $file;
if ($file == "." || $file == "..") {
continue;
} else {
if (@is_dir($fullname)) {
if (empty ($this->options['recurse'])) {
continue;
}
$temp = $this->parse_dir($fullname);
foreach ($temp as $file2) {
$files[] = $file2;
}
} else {
if (@file_exists($fullname)) {
$files[] = array('name' => $fullname, 'name2' => $this->options['prepend'] .
preg_replace(
"/(\.+\/+)+/", "", ($this->options['storepaths'] == 0 && strstr($fullname, "/")) ?
substr($fullname, strrpos($fullname, "/") + 1) : $fullname
),
'type' => @is_link($fullname) && $this->options['followlinks'] == 0 ? 2 : 0,
'ext' => substr($file, strrpos($file, ".")), 'stat' => stat($fullname));
}
}
}
}
@closedir($dir);
return $files;
}
function sort_files($a, $b)
{
if ($a['type'] != $b['type']) {
if ($a['type'] == 5 || $b['type'] == 2) {
return -1;
} else {
if ($a['type'] == 2 || $b['type'] == 5) {
return 1;
} else {
if ($a['type'] == 5) {
return strcmp(strtolower($a['name']), strtolower($b['name']));
} else {
if ($a['ext'] != $b['ext']) {
return strcmp($a['ext'], $b['ext']);
} else {
if ($a['stat'][7] != $b['stat'][7]) {
return $a['stat'][7] > $b['stat'][7] ? -1 : 1;
} else {
return strcmp(strtolower($a['name']), strtolower($b['name']));
}
}
}
}
}
}
return 0;
}
function download_file()
{
if ($this->options['inmemory'] == 0) {
$this->error[]
= "Can only use download_file() if archive is in memory. Redirect to file otherwise, it is faster.";
return;
}
switch ($this->options['type']) {
case "zip":
header("Content-Type: application/zip");
break;
case "bzip":
header("Content-Type: application/x-bzip2");
break;
case "gzip":
header("Content-Type: application/x-gzip");
break;
case "tar":
header("Content-Type: application/x-tar");
}
$header = "Content-Disposition: attachment; filename=\"";
$header .= strstr($this->options['name'], "/") ? substr(
$this->options['name'], strrpos($this->options['name'], "/") + 1
) : $this->options['name'];
$header .= "\"";
header($header);
header("Content-Length: " . strlen($this->archive));
header("Content-Transfer-Encoding: binary");
header("Cache-Control: no-cache, must-revalidate, max-age=60");
header("Expires: Sat, 01 Jan 2000 12:00:00 GMT");
print($this->archive);
}
}
class tar_file extends archive
{
function tar_file($name)
{
$this->archive($name);
$this->options['type'] = "tar";
}
function create_tar()
{
$pwd = getcwd();
chdir($this->options['basedir']);
foreach ($this->files as $current) {
if ($current['name'] == $this->options['name']) {
continue;
}
if (strlen($current['name2']) > 99) {
$path = substr(
$current['name2'], 0, strpos($current['name2'], "/", strlen($current['name2']) - 100) + 1
);
$current['name2'] = substr($current['name2'], strlen($path));
if (strlen($path) > 154 || strlen($current['name2']) > 99) {
$this->error[]
= "Could not add {$path}{$current['name2']} to archive because the filename is too long.";
continue;
}
}
$block = pack(
"a100a8a8a8a12a12a8a1a100a6a2a32a32a8a8a155a12", $current['name2'], sprintf(
"%07o",
$current['stat'][2]
), sprintf("%07o", $current['stat'][4]), sprintf("%07o", $current['stat'][5]),
sprintf("%011o", $current['type'] == 2 ? 0 : $current['stat'][7]),
sprintf("%011o", $current['stat'][9]),
" ", $current['type'], $current['type'] == 2 ? @readlink($current['name']) : "", "ustar ", " ",
"Unknown", "Unknown", "", "", !empty ($path) ? $path : "", ""
);
$checksum = 0;
for ($i = 0; $i < 512; $i++) {
$checksum += ord(substr($block, $i, 1));
}
$checksum = pack("a8", sprintf("%07o", $checksum));
$block = substr_replace($block, $checksum, 148, 8);
if ($current['type'] == 2 || $current['stat'][7] == 0) {
$this->add_data($block);
} else {
if ($fp = @fopen($current['name'], "rb")) {
$this->add_data($block);
while ($temp = fread($fp, 1048576)) {
$this->add_data($temp);
}
if ($current['stat'][7] % 512 > 0) {
$temp = "";
for ($i = 0; $i < 512 - $current['stat'][7] % 512; $i++) {
$temp .= "\0";
}
$this->add_data($temp);
}
fclose($fp);
} else {
$this->error[] = "Could not open file {$current['name']} for reading. It was not added.";
}
}
}
$this->add_data(pack("a1024", ""));
chdir($pwd);
return 1;
}
function extract_files()
{
$pwd = getcwd();
chdir($this->options['basedir']);
if ($fp = $this->open_archive()) {
if ($this->options['inmemory'] == 1) {
$this->files = array();
}
while ($block = fread($fp, 512)) {
$temp = unpack(
"a100name/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1type/a100symlink/a6magic/a2temp/a32temp/a32temp/a8temp/a8temp/a155prefix/a12temp",
$block
);
$file = array(
'name' => $temp['prefix'] . $temp['name'],
'stat' => array(
2 => $temp['mode'],
4 => octdec($temp['uid']),
5 => octdec($temp['gid']),
7 => octdec($temp['size']),
9 => octdec($temp['mtime']),
),
'checksum' => octdec($temp['checksum']),
'type' => $temp['type'],
'magic' => $temp['magic'],
);
if ($file['checksum'] == 0x00000000) {
break;
} else {
if (substr($file['magic'], 0, 5) != "ustar") {
$this->error[] = "This script does not support extracting this type of tar file.";
break;
}
}
$block = substr_replace($block, " ", 148, 8);
$checksum = 0;
for ($i = 0; $i < 512; $i++) {
$checksum += ord(substr($block, $i, 1));
}
if ($file['checksum'] != $checksum) {
$this->error[] = "Could not extract from {$this->options['name']}, it is corrupt.";
}
if ($this->options['inmemory'] == 1) {
$file['data'] = fread($fp, $file['stat'][7]);
fread($fp, (512 - $file['stat'][7] % 512) == 512 ? 0 : (512 - $file['stat'][7] % 512));
unset ($file['checksum'], $file['magic']);
$this->files[] = $file;
} else {
if ($file['type'] == 5) {
if (!is_dir($file['name'])) {
mkdir($file['name'], $file['stat'][2]);
}
} else {
if ($this->options['overwrite'] == 0 && file_exists($file['name'])) {
$this->error[] = "{$file['name']} already exists.";
continue;
} else {
if ($file['type'] == 2) {
symlink($temp['symlink'], $file['name']);
chmod($file['name'], $file['stat'][2]);
} else {
if ($new = @fopen($file['name'], "wb")) {
fwrite($new, fread($fp, $file['stat'][7]));
// 0 throws a warning (?)
@fread(
$fp, (512 - $file['stat'][7] % 512) == 512 ? 0 : (512 - $file['stat'][7] % 512)
);
fclose($new);
chmod($file['name'], $file['stat'][2]);
} else {
$this->error[] = "Could not open {$file['name']} for writing.";
continue;
}
}
}
}
}
chmod($file['name'], 0755);
touch($file['name'], $file['stat'][9]);
unset ($file);
}
} else {
$this->error[] = "Could not open file {$this->options['name']}";
}
chdir($pwd);
}
function open_archive()
{
return @fopen($this->options['name'], "rb");
}
}
class gzip_file extends tar_file
{
function gzip_file($name)
{
$this->tar_file($name);
$this->options['type'] = "gzip";
}
function create_gzip()
{
if ($this->options['inmemory'] == 0) {
$pwd = getcwd();
chdir($this->options['basedir']);
if ($fp = gzopen($this->options['name'], "wb{$this->options['level']}")) {
fseek($this->archive, 0);
while ($temp = fread($this->archive, 1048576)) {
gzwrite($fp, $temp);
}
gzclose($fp);
chdir($pwd);
} else {
$this->error[] = "Could not open {$this->options['name']} for writing.";
chdir($pwd);
return 0;
}
} else {
$this->archive = gzencode($this->archive, $this->options['level']);
}
return 1;
}
function open_archive()
{
return @gzopen($this->options['name'], "rb");
}
}
class bzip_file extends tar_file
{
function bzip_file($name)
{
$this->tar_file($name);
$this->options['type'] = "bzip";
}
function create_bzip()
{
if ($this->options['inmemory'] == 0) {
$pwd = getcwd();
chdir($this->options['basedir']);
if ($fp = bzopen($this->options['name'], "wb")) {
fseek($this->archive, 0);
while ($temp = fread($this->archive, 1048576)) {
bzwrite($fp, $temp);
}
bzclose($fp);
chdir($pwd);
} else {
$this->error[] = "Could not open {$this->options['name']} for writing.";
chdir($pwd);
return 0;
}
} else {
$this->archive = bzcompress($this->archive, $this->options['level']);
}
return 1;
}
function open_archive()
{
return @bzopen($this->options['name'], "rb");
}
}
class zip_file extends archive
{
//this function was added by Jonas Brekle
//might have problems with compatibility
function extract_files()
{
$pwd = getcwd();
chdir($this->options['basedir']);
$zip = new ZipArchive();
if ($zip->open($this->options['name'])) {
$zip->extractTo($this->options['basedir']);
$zip->close();
}
chdir($pwd);
}
function zip_file($name)
{
$this->archive($name);
$this->options['type'] = "zip";
}
function create_zip()
{
$files = 0;
$offset = 0;
$central = "";
if (!empty ($this->options['sfx'])) {
if ($fp = @fopen($this->options['sfx'], "rb")) {
$temp = fread($fp, filesize($this->options['sfx']));
fclose($fp);
$this->add_data($temp);
$offset += strlen($temp);
unset ($temp);
} else {
$this->error[] = "Could not open sfx module from {$this->options['sfx']}.";
}
}
$pwd = getcwd();
chdir($this->options['basedir']);
foreach ($this->files as $current) {
if ($current['name'] == $this->options['name']) {
continue;
}
$timedate = explode(" ", date("Y n j G i s", $current['stat'][9]));
$timedate = ($timedate[0] - 1980 << 25) | ($timedate[1] << 21) | ($timedate[2] << 16) |
($timedate[3] << 11) | ($timedate[4] << 5) | ($timedate[5]);
$block = pack(
"VvvvV", 0x04034b50, 0x000A, 0x0000,
(isset($current['method']) || $this->options['method'] == 0) ? 0x0000 : 0x0008, $timedate
);
if ($current['stat'][7] == 0 && $current['type'] == 5) {
$block .= pack("VVVvv", 0x00000000, 0x00000000, 0x00000000, strlen($current['name2']) + 1, 0x0000);
$block .= $current['name2'] . "/";
$this->add_data($block);
$central .= pack(
"VvvvvVVVVvvvvvVV", 0x02014b50, 0x0014, $this->options['method'] == 0 ? 0x0000 : 0x000A, 0x0000,
(isset($current['method']) || $this->options['method'] == 0) ? 0x0000 : 0x0008, $timedate,
0x00000000, 0x00000000, 0x00000000, strlen($current['name2']) + 1, 0x0000, 0x0000, 0x0000, 0x0000,
$current['type'] == 5 ? 0x00000010 : 0x00000000, $offset
);
$central .= $current['name2'] . "/";
$files++;
$offset += (31 + strlen($current['name2']));
} else {
if ($current['stat'][7] == 0) {
$block .= pack("VVVvv", 0x00000000, 0x00000000, 0x00000000, strlen($current['name2']), 0x0000);
$block .= $current['name2'];
$this->add_data($block);
$central .= pack(
"VvvvvVVVVvvvvvVV", 0x02014b50, 0x0014, $this->options['method'] == 0 ? 0x0000 : 0x000A, 0x0000,
(isset($current['method']) || $this->options['method'] == 0) ? 0x0000 : 0x0008, $timedate,
0x00000000, 0x00000000, 0x00000000, strlen($current['name2']), 0x0000, 0x0000, 0x0000, 0x0000,
$current['type'] == 5 ? 0x00000010 : 0x00000000, $offset
);
$central .= $current['name2'];
$files++;
$offset += (30 + strlen($current['name2']));
} else {
if ($fp = @fopen($current['name'], "rb")) {
$temp = fread($fp, $current['stat'][7]);
fclose($fp);
$crc32 = crc32($temp);
if (!isset($current['method']) && $this->options['method'] == 1) {
$temp = gzcompress($temp, $this->options['level']);
$size = strlen($temp) - 6;
$temp = substr($temp, 2, $size);
} else {
$size = strlen($temp);
}
$block .= pack("VVVvv", $crc32, $size, $current['stat'][7], strlen($current['name2']), 0x0000);
$block .= $current['name2'];
$this->add_data($block);
$this->add_data($temp);
unset ($temp);
$central .= pack(
"VvvvvVVVVvvvvvVV", 0x02014b50, 0x0014, $this->options['method'] == 0 ? 0x0000 : 0x000A,
0x0000,
(isset($current['method']) || $this->options['method'] == 0) ? 0x0000 : 0x0008, $timedate,
$crc32, $size, $current['stat'][7], strlen($current['name2']), 0x0000, 0x0000, 0x0000,
0x0000,
0x00000000, $offset
);
$central .= $current['name2'];
$files++;
$offset += (30 + strlen($current['name2']) + $size);
} else {
$this->error[] = "Could not open file {$current['name']} for reading. It was not added.";
}
}
}
}
$this->add_data($central);
$this->add_data(
pack(
"VvvvvVVv", 0x06054b50, 0x0000, 0x0000, $files, $files, strlen($central), $offset,
!empty ($this->options['comment']) ? strlen($this->options['comment']) : 0x0000
)
);
if (!empty ($this->options['comment'])) {
$this->add_data($this->options['comment']);
}
chdir($pwd);
return 1;
}
}
?>
================================================
FILE: extensions/exconf/ExconfController.php
================================================
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class ExconfController extends OntoWiki_Controller_Component
{
const EXTENSION_CLASS = 'http://usefulinc.com/ns/doap#Project';
const VERSION_CLASS = 'http://usefulinc.com/ns/doap#Version';
const EXTENSION_TITLE_PROPERTY = 'http://www.w3.org/2000/01/rdf-schema#label'; //rdfs:label
const EXTENSION_NAME_PROPERTY = 'http://usefulinc.com/ns/doap#name'; //doap:name
const EXTENSION_DESCRIPTION_PROPERTY = 'http://usefulinc.com/ns/doap#description'; //doap:description
const EXTENSION_RELEASELOCATION_PROPERTY = 'http://usefulinc.com/ns/doap#file-release';
const EXTENSION_RELEASE_PROPERTY = 'http://usefulinc.com/ns/doap#release';
const EXTENSION_PAGE_PROPERTY = 'http://usefulinc.com/ns/doap#homepage';
const EXTENSION_RELEASE_ID_PROPERTY = 'http://usefulinc.com/ns/doap#revision';
const EXTENSION_AUTHOR_PROPERTY = 'http://usefulinc.com/ns/doap#maintainer';
const EXTENSION_AUTHORLABEL_PROPERTY = 'http://xmlns.com/foaf/0.1/name';
const EXTENSION_AUTHORPAGE_PROPERTY = 'http://xmlns.com/foaf/0.1/homepage';
const EXTENSION_AUTHORMAIL_PROPERTY = 'http://xmlns.com/foaf/0.1/mbox';
const EXTENSION_MINOWVERSION_PROPERTY = 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/minOWVersion';
const EXTENSION_NS = 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/';
protected $_useFtp = false;
protected $_folderWriteable = true;
protected $_connection = null;
protected $_sftp = null;
public function __call($method, $args)
{
$this->_forward('list');
}
public function init()
{
parent::init();
$nav = OntoWiki::getInstance()->getNavigation();
$nav->reset();
$nav->register(
'list',
array(
'route' => null,
'action' => 'list',
'controller' => 'exconf',
'name' => 'Locally Installed'
)
);
$nav->register(
'repo',
array(
'route' => null,
'action' => 'explorerepo',
'controller' => 'exconf',
'name' => 'Install / Upgrade from Repo'
)
);
$ow = OntoWiki::getInstance();
$modMan = $ow->extensionManager;
//determine how to write to the filesystem
if (!is_writeable($modMan->getExtensionPath())) {
$con = $this->ftpConnect();
if ($con->connection == null) {
$this->_folderWriteable = false;
$this->_connection = false;
$this->_sftp = false;
} else {
$this->_useFtp = true;
$this->_connection = $con->connection;
$this->_sftp = $con->sftp;
}
}
}
public function listAction()
{
$this->view->placeholder('main.window.title')->set($this->_owApp->translate->_('Configure Extensions'));
$this->addModuleContext('main.window.exconf');
$ow = OntoWiki::getInstance();
if (!$this->_erfurt->getAc()->isActionAllowed('ExtensionConfiguration')
&& !$this->_request->isXmlHttpRequest()
) {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message('config not allowed for this user', OntoWiki_Message::ERROR)
);
$this->view->isAllowed = false;
$extensions = array();
} else {
$this->view->isAllowed = true;
//get extension from manager
$modMan = $ow->extensionManager;
$extensions = $modMan->getExtensions();
//sort by name property
$volume = array();
foreach ($extensions as $key => $row) {
$volume[$key] = $row->title;
}
array_multisort($volume, SORT_ASC, $extensions);
//some statistics
$numEnabled = 0;
$numDisabled = 0;
foreach ($extensions as $extension) {
if ($extension->enabled) {
$numEnabled++;
} else {
$numDisabled++;
}
}
$numAll = count($extensions);
//save to view
$this->view->numEnabled = $numEnabled;
$this->view->numDisabled = $numDisabled;
$this->view->numAll = $numAll;
if (!is_writeable($modMan->getExtensionPath())) {
if (!$this->_request->isXmlHttpRequest()) {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message(
"the extension folder '" . $modMan->getExtensionPath() . "' is not writeable." .
" no changes can be made",
OntoWiki_Message::WARNING
)
);
}
}
$this->view->coreExtensions = $this->_config->extensions->core->toArray();
}
$this->view->extensions = $extensions;
}
public function confAction()
{
OntoWiki::getInstance()->getNavigation()->disableNavigation();
$this->view->placeholder('main.window.title')->set(
$this->_owApp->translate->_('Configure ') . ' ' . $this->_request->getParam('name')
);
if (!$this->_erfurt->getAc()->isActionAllowed('ExtensionConfiguration')) {
throw new OntoWiki_Exception('config not allowed for this user');
} else {
if (!isset($this->_request->name)) {
throw new OntoWiki_Exception("param 'name' needs to be passed to this action");
}
$ow = OntoWiki::getInstance();
$toolbar = $ow->toolbar;
$urlList = new OntoWiki_Url(array('controller' => 'exconf', 'action' => 'list'), array());
$urlConf = new OntoWiki_Url(array('controller' => 'exconf', 'action' => 'conf'), array());
$urlConf->restore = 1;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'save'))
->appendButton(
OntoWiki_Toolbar::CANCEL,
array('name' => 'back', 'class' => '', 'url' => (string)$urlList)
)
->appendButton(
OntoWiki_Toolbar::EDIT,
array('name' => 'restore defaults', 'class' => '', 'url' => (string)$urlConf)
);
// add toolbar
$this->view->placeholder('main.window.toolbar')->set($toolbar);
$name = $this->_request->getParam('name');
$manager = $ow->extensionManager;
$dirPath = $manager->getExtensionPath() . $name . DIRECTORY_SEPARATOR;
if (!is_dir($dirPath)) {
throw new OntoWiki_Exception('invalid extension - ' . $dirPath . ' does not exist or no folder');
}
$localIniPath = $manager->getExtensionPath() . $name . ".ini";
$privateConfig = $manager->getPrivateConfig($name);
$config = ($privateConfig != null ? $privateConfig->toArray() : array());
$this->view->enabled = $manager->isExtensionActive($name);
$fullConfig = $manager->getExtensionConfig($name);
$this->view->isCoreExtension = isset($fullConfig->isCoreExtension) && $fullConfig->isCoreExtension;
$this->view->config = $config;
$this->view->name = $name;
$this->view->coreExtensions = $this->_config->extensions->core->toArray();
if (!is_writeable($manager->getExtensionPath())) {
if (!$this->_request->isXmlHttpRequest()) {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message(
"the extension folder '" . $manager->getExtensionPath() . "' is not writeable. " .
'no changes can be made',
OntoWiki_Message::WARNING
)
);
}
} else {
//react on post data
if (isset($this->_request->remove)) {
if (self::rrmdir($dirPath)) {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message('extension deleted', OntoWiki_Message::SUCCESS)
);
$this->_redirect($this->urlBase . 'exconf/list');
} else {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message('extension could not be deleted', OntoWiki_Message::ERROR)
);
}
}
//the togglebuttons in the extension list action, send only a new enabled state
if (isset($this->_request->enabled)) {
if (!file_exists($localIniPath)) {
@touch($localIniPath);
chmod($localIniPath, 0777);
}
$ini = new Zend_Config_Ini($localIniPath, null, array('allowModifications' => true));
$ini->enabled = $this->_request->getParam('enabled') == "true";
$writer = new Zend_Config_Writer_Ini(array());
$writer->write($localIniPath, $ini, true);
//invalidate the cache to get changes distributed
$cache = OntoWiki::getInstance()->getCache();
$cache->remove('ow_extensionConfig');
}
// the conf action sends a complete config array as json
if (isset($this->_request->config)) {
$arr = json_decode($this->_request->getParam('config'), true);
if ($arr == null) {
throw new OntoWiki_Exception('invalid json: ' . $this->_request->getParam('config'));
} else {
if (!file_exists($localIniPath)) {
@touch($localIniPath);
chmod($localIniPath, 0777);
}
//only modification of the private section and the enabled-property are allowed
foreach ($arr as $key => $val) {
if ($key != 'enabled' && $key != 'private') {
unset($arr[$key]);
}
}
$writer = new Zend_Config_Writer_Ini(array());
$postIni = new Zend_Config($arr, true);
$writer->write($localIniPath, $postIni, true);
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message('config sucessfully changed', OntoWiki_Message::SUCCESS)
);
//invalidate the cache to get changes distributed
$cache = OntoWiki::getInstance()->getCache();
$cache->remove('ow_extensionConfig');
}
$this->_redirect($this->urlBase . 'exconf/conf/?name=' . $name);
}
if (isset($this->_request->reset)) {
if (@unlink($localIniPath)) {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message(
'config sucessfully reverted to default',
OntoWiki_Message::SUCCESS
)
);
} else {
OntoWiki::getInstance()->appendMessage(
new OntoWiki_Message(
'config not reverted to default - not existing or not writeable',
OntoWiki_Message::ERROR
)
);
}
$this->_redirect($this->urlBase . 'exconf/conf/?name=' . $name);
}
}
}
if ($this->_request->isXmlHttpRequest()) {
//no rendering
$this->_helper->viewRenderer->setNoRender();
}
}
public function explorerepoAction()
{
$this->view->placeholder('main.window.title')->set($this->_owApp->translate->_('Explore Repo'));
if (!$this->_erfurt->getAc()->isActionAllowed('ExtensionConfiguration')) {
throw new OntoWiki_Exception('config not allowed for this user');
}
$repoUrl = $this->_privateConfig->repoUrl;
if (($otherRepo = $this->getParam('repoUrl')) != null) {
$repoUrl = $otherRepo;
}
$graph = $this->_privateConfig->graph;
if (($otherGraph = $this->getParam('graph')) != null) {
$graph = $otherGraph;
}
$this->view->repoUrl = $repoUrl;
$this->view->graph = $graph;
$ow = OntoWiki::getInstance();
$ow->appendMessage(new OntoWiki_Message('Repository: ' . $repoUrl, OntoWiki_Message::INFO));
//define the list on a new store, that queries a sparql endpoint
$adapter = new Erfurt_Store_Adapter_Sparql(array('serviceUrl' => $repoUrl, 'graphs' => array($graph)));
$store = new Erfurt_Store(array('adapterInstance' => $adapter), 'sparql');
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
$listName = 'extensions';
if ($listHelper->listExists($listName)) {
$list = $listHelper->getList($listName);
$list->setStore($store);
$list->invalidate(); //remote repo may change data
$listHelper->addList($listName, $list, $this->view, 'list_extensions_main');
} else {
$rdfGraphObj = new Erfurt_Rdf_Model($graph);
$list = new OntoWiki_Model_Instances($store, $rdfGraphObj, array(Erfurt_Store::USE_CACHE => false));
$list->addTypeFilter(self::VERSION_CLASS, null, array('withChilds' => false));
//the version needs to be related to a project (inverse)
$projectVar = new Erfurt_Sparql_Query2_Var('project');
$list->addTripleFilter(
array(
new Erfurt_Sparql_Query2_Triple(
$projectVar,
new Erfurt_Sparql_Query2_IriRef(self::EXTENSION_RELEASE_PROPERTY),
$list->getResourceVar()
)
)
);
//internal name (folder name)
$this->addProjectProperty(self::EXTENSION_NAME_PROPERTY, $projectVar, $list, 'name');
//pretty name (label)
$this->addProjectProperty(self::EXTENSION_TITLE_PROPERTY, $projectVar, $list, 'title');
$this->addProjectProperty(self::EXTENSION_DESCRIPTION_PROPERTY, $projectVar, $list);
$this->addProjectProperty(self::EXTENSION_PAGE_PROPERTY, $projectVar, $list);
$this->addProjectProperty(self::EXTENSION_AUTHOR_PROPERTY, $projectVar, $list);
$this->addAuthorProperty(self::EXTENSION_AUTHORLABEL_PROPERTY, $projectVar, $list, 'authorLabel');
$this->addAuthorProperty(self::EXTENSION_AUTHORPAGE_PROPERTY, $projectVar, $list);
$this->addAuthorProperty(self::EXTENSION_AUTHORMAIL_PROPERTY, $projectVar, $list);
//properties of the versions
$list->addShownProperty(self::EXTENSION_RELEASELOCATION_PROPERTY, 'zip');
$list->addShownProperty(self::EXTENSION_RELEASE_ID_PROPERTY, 'revision');
$list->addShownProperty(self::EXTENSION_MINOWVERSION_PROPERTY, 'minOwVersion');
$listHelper->addListPermanently($listName, $list, $this->view, 'list_extensions_main');
}
}
private function addProjectProperty($p, $projectVar, $list, $name = null)
{
$pIri = new Erfurt_Sparql_Query2_IriRef($p);
if ($name == null) {
$var = new Erfurt_Sparql_Query2_Var($pIri);
} else {
$var = new Erfurt_Sparql_Query2_Var($name);
}
$projectVar = new Erfurt_Sparql_Query2_Var($projectVar->getName() . substr(md5($pIri), 0, 5));
$versionToProjectTriple = new Erfurt_Sparql_Query2_Triple(
$projectVar,
new Erfurt_Sparql_Query2_IriRef(self::EXTENSION_RELEASE_PROPERTY),
$list->getResourceVar()
);
$projectPropertyTriple = new Erfurt_Sparql_Query2_Triple($projectVar, $pIri, $var);
$list->addShownPropertyCustom(array($versionToProjectTriple, $projectPropertyTriple), $var);
}
private function addAuthorProperty($p, $projectVar, $list, $name = null)
{
$pIri = new Erfurt_Sparql_Query2_IriRef($p);
if ($name == null) {
$var = new Erfurt_Sparql_Query2_Var($pIri);
} else {
$var = new Erfurt_Sparql_Query2_Var($name);
}
$projectVar = new Erfurt_Sparql_Query2_Var($projectVar->getName() . substr(md5($pIri), 0, 5));
//for each property a new author var
$authorVar = new Erfurt_Sparql_Query2_Var('author' . substr(md5($pIri), 0, 5));
$versionToProjectTriple = new Erfurt_Sparql_Query2_Triple(
$projectVar,
new Erfurt_Sparql_Query2_IriRef(self::EXTENSION_RELEASE_PROPERTY),
$list->getResourceVar()
);
$projectToAuthorTriple = new Erfurt_Sparql_Query2_Triple(
$projectVar,
new Erfurt_Sparql_Query2_IriRef(self::EXTENSION_AUTHOR_PROPERTY),
$authorVar
);
$authorPropertyTriple = new Erfurt_Sparql_Query2_Triple($authorVar, $pIri, $var);
$list->addShownPropertyCustom(
array($versionToProjectTriple, $projectToAuthorTriple, $authorPropertyTriple),
$var
);
}
/**
* download a archive file from a remote webserver
*/
public function installarchiveremoteAction()
{
$ontoWiki = OntoWiki::getInstance();
$url = $this->getParam('url', '');
$name = $this->getParam('name', '');
if ($url == '' || $name == '') {
$ontoWiki->appendMessage(new OntoWiki_Message('parameters url and name needed.', OntoWiki_Message::ERROR));
} else {
$fileStr = file_get_contents($url);
if ($fileStr != false) {
$tmp = sys_get_temp_dir();
if (!(substr($tmp, -1) == PATH_SEPARATOR)) {
$tmp .= PATH_SEPARATOR;
}
$tmpfname = tempnam($tmp, 'OW_downloadedArchive.zip');
$localFilehandle = fopen($tmpfname, 'w+');
fwrite($localFilehandle, $fileStr);
rewind($localFilehandle);
$this->installArchive($tmpfname, $name);
fclose($localFilehandle); //deletes file
} else {
$ontoWiki->appendMessage(new OntoWiki_Message('could not download.', OntoWiki_Message::ERROR));
}
}
}
/**
* display a upload form
*/
public function archiveuploadformAction()
{
$this->view->placeholder('main.window.title')->set('Upload new extension archive');
$this->view->formActionUrl = $this->_config->urlBase . 'exconf/installarchiveupload';
$this->view->formEncoding = 'multipart/form-data';
$this->view->formClass = 'simple-input input-justify-left';
$this->view->formMethod = 'post';
$this->view->formName = 'archiveupload';
$toolbar = $this->_owApp->toolbar;
$toolbar->appendButton(OntoWiki_Toolbar::SUBMIT, array('name' => 'Upload Archive', 'id' => 'archiveupload'))
->appendButton(OntoWiki_Toolbar::RESET, array('name' => 'Cancel', 'id' => 'archiveupload'));
$this->view->placeholder('main.window.toolbar')->set($toolbar);
}
/**
* handle a archive upload (from browser)
*/
public function installarchiveuploadAction()
{
$ontoWiki = OntoWiki::getInstance();
$upload = new Zend_File_Transfer();
$filesArray = $upload->getFileInfo();
if ($filesArray['archive_file']['error'] == UPLOAD_ERR_OK) {
// upload ok,
$tmpName = $filesArray['archive_file']['tmp_name'];
$cachedir = ini_get('upload_tmp_dir');
$name = $this->getParam('name', "");
if ($name == '') {
$ontoWiki->appendMessage(
new OntoWiki_Message('parameters url and name needed.', OntoWiki_Message::ERROR)
);
} else {
$this->installArchive($cachedir . $tmpName, $name);
}
} else {
$ontoWiki->appendMessage(new OntoWiki_Message('upload error.', OntoWiki_Message::ERROR));
}
}
/**
* handle a uploaded archive (from browser or remote webserver)
* extract it to extension dir
*
* @param $filePath
* @param $fileHandle
*/
protected function installArchive($filePath, $name)
{
require_once 'pclzip.lib.php';
$ext = mime_content_type($filePath);
$this->view->success = false;
$ontoWiki = OntoWiki::getInstance();
switch ($ext) {
case 'application/zip':
$this->view->success = true;
$zip = new PclZip($filePath);
$modMan = $ontoWiki->extensionManager;
$path = $modMan->getExtensionPath();
//check the uploaded archive
$content = $zip->listContent();
$toplevelItem = null;
$tooManyTopLevelItems = false; //only 1 allowed
$sumBytes = 0;
foreach ($content as $key => $item) {
$level = substr_count($item['filename'], '/');
if ($level == 1 && substr($item['filename'], -1, 1) == DIRECTORY_SEPARATOR) {
if ($toplevelItem === null) {
$toplevelItem = $key;
} else {
$tooManyTopLevelItems = true;
break;
}
}
$sumBytes += $item['size'];
if ($sumBytes >= 10000000) {
break;
}
}
// extract contents of archive to disk (extension dir)
//only one item at top level allowed and max. 10MioB
if (!$tooManyTopLevelItems && $sumBytes < 10000000) {
$folderName = substr($content[$toplevelItem]['filename'], 0, -1);
if (file_exists($path . $folderName)) {
self::rrmdir($path . $folderName);
}
$zip->extract(PCLZIP_OPT_PATH, $path);
if (file_exists($path . $folderName)) {
if ($folderName != $name) {
rename($path . $folderName, $path . $name); //move folder to expected name
$folderName = $name;
}
// make all writable
// otherwise, they can only be deleted by users www-data or root
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path . $folderName),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iterator as $key => $handle) {
chmod($handle->__toString(), 0777);
}
$ontoWiki->appendMessage(
new OntoWiki_Message($folderName . ' extension installed.', OntoWiki_Message::SUCCESS)
);
} else {
$ontoWiki->appendMessage(
new OntoWiki_Message(
'archiv could not be extracted. check permissions of extensions folder.',
OntoWiki_Message::ERROR
)
);
}
} else {
$ontoWiki->appendMessage(
new OntoWiki_Message(
'uploaded archive was not accepted (must be < 10MB, and contain one folder).',
OntoWiki_Message::ERROR
)
);
}
break;
default :
$ontoWiki->appendMessage(
new OntoWiki_Message(
'uploaded archive type was not accepted (must be zip).',
OntoWiki_Message::ERROR
)
);
break;
}
// invalidate ExtensionManager cache because a new extension was installed
$ontoWiki->getCache()->remove('ow_extensionConfig');
$url = new OntoWiki_Url(array('controller' => 'exconf', 'action' => 'explorerepo'));
$this->_redirect($url);
}
/**
* Get the connection to ftp-server
*
* @param unknown_type $sftp
* @param unknown_type $connection
*/
public function ftpConnect()
{
if (isset($this->_privateConfig->ftp)) {
$username = $this->_privateConfig->ftp->username;
$password = $this->_privateConfig->ftp->password;
$hostname = $this->_privateConfig->ftp->hostname;
$connection = ssh2_connect($hostname, 22);
ssh2_auth_password($connection, $username, $password);
$sftp = ssh2_sftp($connection);
$ret = new stdClass();
$ret->connection = $connection;
$ret->sftp = $sftp;
return $ret;
} else {
$ret = new stdClass();
$ret->connection = null;
$ret->sftp = null;
return $ret;
}
}
private static function checkRightsRec($dir)
{
$right = is_writable($dir);
if ($right && is_dir($dir)) {
$objects = scandir($dir);
$curObjRight = false;
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
$curObjRight = self::checkRightsRec($dir . DIRECTORY_SEPARATOR . $object);
if (!$curObjRight) {
$right = false;
}
}
}
}
return $right;
}
private static function rrmdir($dir, $check = true)
{
if ($check) {
if (!self::checkRightsRec($dir)) {
return false;
}
}
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
if (is_dir($dir . DIRECTORY_SEPARATOR . $object)) {
self::rrmdir($dir . DIRECTORY_SEPARATOR . $object, false);
} else {
unlink($dir . DIRECTORY_SEPARATOR . $object);
}
}
}
reset($objects);
rmdir($dir);
}
return true;
}
}
================================================
FILE: extensions/exconf/ExconfHelper.php
================================================
getAc()->isActionAllowed('ExtensionConfiguration')) {
$owApp = OntoWiki::getInstance();
$translate = $owApp->translate;
$url = new OntoWiki_Url(array('controller' => 'exconf', 'action' => 'list'), array());
$extrasMenu = OntoWiki_Menu_Registry::getInstance()->getMenu('application')->getSubMenu('Extras');
$extrasMenu->setEntry($translate->_('Configure Extensions'), (string)$url);
}
}
}
================================================
FILE: extensions/exconf/OutlineModule.php
================================================
view->headScript()->appendFile($this->view->moduleUrl . '/resources/outline.js');
$content = '';
return $content;
}
public function shouldShow()
{
return true;
}
}
================================================
FILE: extensions/exconf/default.ini
================================================
;;
; Basic component configuration
;;
enabled = true
name = "Extensions Configuration"
description = "provides this component to configure / toggle extensions."
author = "AKSW"
authorUrl = "http://aksw.org"
modules.outline.title = "Extension Outline"
modules.outline.caching = no
modules.outline.priority = 4
modules.outline.contexts.0 = "main.window.exconf"
templates = "templates"
; languages = "languages/"
isCoreExtension = true
;;
; Component's private configuration
; Anything set below will be available within the component ($this->_privateConfig->key)
;;
[private]
repoUrl = "http://extensions.ontowiki.net/index.php/service/sparql"
graph = "http://extensions.ontowiki.net/"
================================================
FILE: extensions/exconf/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :exconf .
:exconf a doap:Project ;
doap:name "exconf" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Extensions Configuration" ;
doap:description "provides this component to configure / toggle extensions." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:templates "templates" ;
:isCoreExtension "true"^^xsd:boolean ;
owconfig:hasModule :Outline .
:Outline a owconfig:Module ;
rdfs:label "Extension Outline" ;
owconfig:caching "false"^^xsd:boolean ;
owconfig:priority "4" ;
owconfig:context "main.window.exconf" .
:exconf :repoUrl ;
:graph ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/exconf/pclzip.lib.php
================================================
zipname = $p_zipname;
$this->zip_fd = 0;
$this->magic_quotes_status = -1;
// ----- Return
return;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function :
// create($p_filelist, $p_add_dir="", $p_remove_dir="")
// create($p_filelist, $p_option, $p_option_value, ...)
// Description :
// This method supports two different synopsis. The first one is historical.
// This method creates a Zip Archive. The Zip file is created in the
// filesystem. The files and directories indicated in $p_filelist
// are added in the archive. See the parameters description for the
// supported format of $p_filelist.
// When a directory is in the list, the directory and its content is added
// in the archive.
// In this synopsis, the function takes an optional variable list of
// options. See bellow the supported options.
// Parameters :
// $p_filelist : An array containing file or directory names, or
// a string containing one filename or one directory name, or
// a string containing a list of filenames and/or directory
// names separated by spaces.
// $p_add_dir : A path to add before the real path of the archived file,
// in order to have it memorized in the archive.
// $p_remove_dir : A path to remove from the real path of the file to archive,
// in order to have a shorter path memorized in the archive.
// When $p_add_dir and $p_remove_dir are set, $p_remove_dir
// is removed first, before $p_add_dir is added.
// Options :
// PCLZIP_OPT_ADD_PATH :
// PCLZIP_OPT_REMOVE_PATH :
// PCLZIP_OPT_REMOVE_ALL_PATH :
// PCLZIP_OPT_COMMENT :
// PCLZIP_CB_PRE_ADD :
// PCLZIP_CB_POST_ADD :
// Return Values :
// 0 on failure,
// The list of the added files, with a status of the add action.
// (see PclZip::listContent() for list entry format)
// --------------------------------------------------------------------------------
function create($p_filelist)
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Set default values
$v_options = array();
$v_options[PCLZIP_OPT_NO_COMPRESSION] = false;
// ----- Look for variable options arguments
$v_size = func_num_args();
// ----- Look for arguments
if ($v_size > 1) {
// ----- Get the arguments
$v_arg_list = func_get_args();
// ----- Remove from the options list the first argument
array_shift($v_arg_list);
$v_size--;
// ----- Look for first arg
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
// ----- Parse the options
$v_result = $this->privParseOptions(
$v_arg_list, $v_size, $v_options,
array(PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_ADD => 'optional',
PCLZIP_CB_POST_ADD => 'optional',
PCLZIP_OPT_NO_COMPRESSION => 'optional',
PCLZIP_OPT_COMMENT => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
//, PCLZIP_OPT_CRYPT => 'optional'
)
);
if ($v_result != 1) {
return 0;
}
} // ----- Look for 2 args
// Here we need to support the first historic synopsis of the
// method.
else {
// ----- Get the first argument
$v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
// ----- Look for the optional second argument
if ($v_size == 2) {
$v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
} else {
if ($v_size > 2) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER,
"Invalid number / type of arguments"
);
return 0;
}
}
}
}
// ----- Look for default option values
$this->privOptionDefaultThreshold($v_options);
// ----- Init
$v_string_list = array();
$v_att_list = array();
$v_filedescr_list = array();
$p_result_list = array();
// ----- Look if the $p_filelist is really an array
if (is_array($p_filelist)) {
// ----- Look if the first element is also an array
// This will mean that this is a file description entry
if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
$v_att_list = $p_filelist;
} // ----- The list is a list of string names
else {
$v_string_list = $p_filelist;
}
} // ----- Look if the $p_filelist is a string
else {
if (is_string($p_filelist)) {
// ----- Create a list from the string
$v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
} // ----- Invalid variable type for $p_filelist
else {
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
return 0;
}
}
// ----- Reformat the string list
if (sizeof($v_string_list) != 0) {
foreach ($v_string_list as $v_string) {
if ($v_string != '') {
$v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
} else {
}
}
}
// ----- For each file in the list check the attributes
$v_supported_attributes
= array(PCLZIP_ATT_FILE_NAME => 'mandatory'
, PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
, PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
, PCLZIP_ATT_FILE_MTIME => 'optional'
, PCLZIP_ATT_FILE_CONTENT => 'optional'
, PCLZIP_ATT_FILE_COMMENT => 'optional'
);
foreach ($v_att_list as $v_entry) {
$v_result = $this->privFileDescrParseAtt(
$v_entry,
$v_filedescr_list[],
$v_options,
$v_supported_attributes
);
if ($v_result != 1) {
return 0;
}
}
// ----- Expand the filelist (expand directories)
$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
if ($v_result != 1) {
return 0;
}
// ----- Call the create fct
$v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
if ($v_result != 1) {
return 0;
}
// ----- Return
return $p_result_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function :
// add($p_filelist, $p_add_dir="", $p_remove_dir="")
// add($p_filelist, $p_option, $p_option_value, ...)
// Description :
// This method supports two synopsis. The first one is historical.
// This methods add the list of files in an existing archive.
// If a file with the same name already exists, it is added at the end of the
// archive, the first one is still present.
// If the archive does not exist, it is created.
// Parameters :
// $p_filelist : An array containing file or directory names, or
// a string containing one filename or one directory name, or
// a string containing a list of filenames and/or directory
// names separated by spaces.
// $p_add_dir : A path to add before the real path of the archived file,
// in order to have it memorized in the archive.
// $p_remove_dir : A path to remove from the real path of the file to archive,
// in order to have a shorter path memorized in the archive.
// When $p_add_dir and $p_remove_dir are set, $p_remove_dir
// is removed first, before $p_add_dir is added.
// Options :
// PCLZIP_OPT_ADD_PATH :
// PCLZIP_OPT_REMOVE_PATH :
// PCLZIP_OPT_REMOVE_ALL_PATH :
// PCLZIP_OPT_COMMENT :
// PCLZIP_OPT_ADD_COMMENT :
// PCLZIP_OPT_PREPEND_COMMENT :
// PCLZIP_CB_PRE_ADD :
// PCLZIP_CB_POST_ADD :
// Return Values :
// 0 on failure,
// The list of the added files, with a status of the add action.
// (see PclZip::listContent() for list entry format)
// --------------------------------------------------------------------------------
function add($p_filelist)
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Set default values
$v_options = array();
$v_options[PCLZIP_OPT_NO_COMPRESSION] = false;
// ----- Look for variable options arguments
$v_size = func_num_args();
// ----- Look for arguments
if ($v_size > 1) {
// ----- Get the arguments
$v_arg_list = func_get_args();
// ----- Remove form the options list the first argument
array_shift($v_arg_list);
$v_size--;
// ----- Look for first arg
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
// ----- Parse the options
$v_result = $this->privParseOptions(
$v_arg_list, $v_size, $v_options,
array(PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_ADD => 'optional',
PCLZIP_CB_POST_ADD => 'optional',
PCLZIP_OPT_NO_COMPRESSION => 'optional',
PCLZIP_OPT_COMMENT => 'optional',
PCLZIP_OPT_ADD_COMMENT => 'optional',
PCLZIP_OPT_PREPEND_COMMENT => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
//, PCLZIP_OPT_CRYPT => 'optional'
)
);
if ($v_result != 1) {
return 0;
}
} // ----- Look for 2 args
// Here we need to support the first historic synopsis of the
// method.
else {
// ----- Get the first argument
$v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
// ----- Look for the optional second argument
if ($v_size == 2) {
$v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
} else {
if ($v_size > 2) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
// ----- Return
return 0;
}
}
}
}
// ----- Look for default option values
$this->privOptionDefaultThreshold($v_options);
// ----- Init
$v_string_list = array();
$v_att_list = array();
$v_filedescr_list = array();
$p_result_list = array();
// ----- Look if the $p_filelist is really an array
if (is_array($p_filelist)) {
// ----- Look if the first element is also an array
// This will mean that this is a file description entry
if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
$v_att_list = $p_filelist;
} // ----- The list is a list of string names
else {
$v_string_list = $p_filelist;
}
} // ----- Look if the $p_filelist is a string
else {
if (is_string($p_filelist)) {
// ----- Create a list from the string
$v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
} // ----- Invalid variable type for $p_filelist
else {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '" . gettype($p_filelist) . "' for p_filelist"
);
return 0;
}
}
// ----- Reformat the string list
if (sizeof($v_string_list) != 0) {
foreach ($v_string_list as $v_string) {
$v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
}
}
// ----- For each file in the list check the attributes
$v_supported_attributes
= array(PCLZIP_ATT_FILE_NAME => 'mandatory'
, PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
, PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
, PCLZIP_ATT_FILE_MTIME => 'optional'
, PCLZIP_ATT_FILE_CONTENT => 'optional'
, PCLZIP_ATT_FILE_COMMENT => 'optional'
);
foreach ($v_att_list as $v_entry) {
$v_result = $this->privFileDescrParseAtt(
$v_entry,
$v_filedescr_list[],
$v_options,
$v_supported_attributes
);
if ($v_result != 1) {
return 0;
}
}
// ----- Expand the filelist (expand directories)
$v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
if ($v_result != 1) {
return 0;
}
// ----- Call the create fct
$v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
if ($v_result != 1) {
return 0;
}
// ----- Return
return $p_result_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : listContent()
// Description :
// This public method, gives the list of the files and directories, with their
// properties.
// The properties of each entries in the list are (used also in other functions) :
// filename : Name of the file. For a create or add action it is the filename
// given by the user. For an extract function it is the filename
// of the extracted file.
// stored_filename : Name of the file / directory stored in the archive.
// size : Size of the stored file.
// compressed_size : Size of the file's data compressed in the archive
// (without the headers overhead)
// mtime : Last known modification date of the file (UNIX timestamp)
// comment : Comment associated with the file
// folder : true | false
// index : index of the file in the archive
// status : status of the action (depending of the action) :
// Values are :
// ok : OK !
// filtered : the file / dir is not extracted (filtered by user)
// already_a_directory : the file can not be extracted because a
// directory with the same name already exists
// write_protected : the file can not be extracted because a file
// with the same name already exists and is
// write protected
// newer_exist : the file was not extracted because a newer file exists
// path_creation_fail : the file is not extracted because the folder
// does not exist and can not be created
// write_error : the file was not extracted because there was a
// error while writing the file
// read_error : the file was not extracted because there was a error
// while reading the file
// invalid_header : the file was not extracted because of an archive
// format error (bad file header)
// Note that each time a method can continue operating when there
// is an action error on a file, the error is only logged in the file status.
// Return Values :
// 0 on an unrecoverable failure,
// The list of the files in the archive.
// --------------------------------------------------------------------------------
function listContent()
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Check archive
if (!$this->privCheckFormat()) {
return (0);
}
// ----- Call the extracting fct
$p_list = array();
if (($v_result = $this->privList($p_list)) != 1) {
unset($p_list);
return (0);
}
// ----- Return
return $p_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function :
// extract($p_path="./", $p_remove_path="")
// extract([$p_option, $p_option_value, ...])
// Description :
// This method supports two synopsis. The first one is historical.
// This method extract all the files / directories from the archive to the
// folder indicated in $p_path.
// If you want to ignore the 'root' part of path of the memorized files
// you can indicate this in the optional $p_remove_path parameter.
// By default, if a newer file with the same name already exists, the
// file is not extracted.
//
// If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
// are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
// at the end of the path value of PCLZIP_OPT_PATH.
// Parameters :
// $p_path : Path where the files and directories are to be extracted
// $p_remove_path : First part ('root' part) of the memorized path
// (if any similar) to remove while extracting.
// Options :
// PCLZIP_OPT_PATH :
// PCLZIP_OPT_ADD_PATH :
// PCLZIP_OPT_REMOVE_PATH :
// PCLZIP_OPT_REMOVE_ALL_PATH :
// PCLZIP_CB_PRE_EXTRACT :
// PCLZIP_CB_POST_EXTRACT :
// Return Values :
// 0 or a negative value on failure,
// The list of the extracted files, with a status of the action.
// (see PclZip::listContent() for list entry format)
// --------------------------------------------------------------------------------
function extract()
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Check archive
if (!$this->privCheckFormat()) {
return (0);
}
// ----- Set default values
$v_options = array();
// $v_path = "./";
$v_path = '';
$v_remove_path = "";
$v_remove_all_path = false;
// ----- Look for variable options arguments
$v_size = func_num_args();
// ----- Default values for option
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
// ----- Look for arguments
if ($v_size > 0) {
// ----- Get the arguments
$v_arg_list = func_get_args();
// ----- Look for first arg
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
// ----- Parse the options
$v_result = $this->privParseOptions(
$v_arg_list, $v_size, $v_options,
array(PCLZIP_OPT_PATH => 'optional',
PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_EXTRACT => 'optional',
PCLZIP_CB_POST_EXTRACT => 'optional',
PCLZIP_OPT_SET_CHMOD => 'optional',
PCLZIP_OPT_BY_NAME => 'optional',
PCLZIP_OPT_BY_EREG => 'optional',
PCLZIP_OPT_BY_PREG => 'optional',
PCLZIP_OPT_BY_INDEX => 'optional',
PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
PCLZIP_OPT_REPLACE_NEWER => 'optional'
, PCLZIP_OPT_STOP_ON_ERROR => 'optional'
, PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
)
);
if ($v_result != 1) {
return 0;
}
// ----- Set the arguments
if (isset($v_options[PCLZIP_OPT_PATH])) {
$v_path = $v_options[PCLZIP_OPT_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
$v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
}
if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
// ----- Check for '/' in last path char
if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
$v_path .= '/';
}
$v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
}
} // ----- Look for 2 args
// Here we need to support the first historic synopsis of the
// method.
else {
// ----- Get the first argument
$v_path = $v_arg_list[0];
// ----- Look for the optional second argument
if ($v_size == 2) {
$v_remove_path = $v_arg_list[1];
} else {
if ($v_size > 2) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
// ----- Return
return 0;
}
}
}
}
// ----- Look for default option values
$this->privOptionDefaultThreshold($v_options);
// ----- Trace
// ----- Call the extracting fct
$p_list = array();
$v_result = $this->privExtractByRule(
$p_list, $v_path, $v_remove_path,
$v_remove_all_path, $v_options
);
if ($v_result < 1) {
unset($p_list);
return (0);
}
// ----- Return
return $p_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function :
// extractByIndex($p_index, $p_path="./", $p_remove_path="")
// extractByIndex($p_index, [$p_option, $p_option_value, ...])
// Description :
// This method supports two synopsis. The first one is historical.
// This method is doing a partial extract of the archive.
// The extracted files or folders are identified by their index in the
// archive (from 0 to n).
// Note that if the index identify a folder, only the folder entry is
// extracted, not all the files included in the archive.
// Parameters :
// $p_index : A single index (integer) or a string of indexes of files to
// extract. The form of the string is "0,4-6,8-12" with only numbers
// and '-' for range or ',' to separate ranges. No spaces or ';'
// are allowed.
// $p_path : Path where the files and directories are to be extracted
// $p_remove_path : First part ('root' part) of the memorized path
// (if any similar) to remove while extracting.
// Options :
// PCLZIP_OPT_PATH :
// PCLZIP_OPT_ADD_PATH :
// PCLZIP_OPT_REMOVE_PATH :
// PCLZIP_OPT_REMOVE_ALL_PATH :
// PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
// not as files.
// The resulting content is in a new field 'content' in the file
// structure.
// This option must be used alone (any other options are ignored).
// PCLZIP_CB_PRE_EXTRACT :
// PCLZIP_CB_POST_EXTRACT :
// Return Values :
// 0 on failure,
// The list of the extracted files, with a status of the action.
// (see PclZip::listContent() for list entry format)
// --------------------------------------------------------------------------------
//function extractByIndex($p_index, options...)
function extractByIndex($p_index)
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Check archive
if (!$this->privCheckFormat()) {
return (0);
}
// ----- Set default values
$v_options = array();
// $v_path = "./";
$v_path = '';
$v_remove_path = "";
$v_remove_all_path = false;
// ----- Look for variable options arguments
$v_size = func_num_args();
// ----- Default values for option
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
// ----- Look for arguments
if ($v_size > 1) {
// ----- Get the arguments
$v_arg_list = func_get_args();
// ----- Remove form the options list the first argument
array_shift($v_arg_list);
$v_size--;
// ----- Look for first arg
if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
// ----- Parse the options
$v_result = $this->privParseOptions(
$v_arg_list, $v_size, $v_options,
array(PCLZIP_OPT_PATH => 'optional',
PCLZIP_OPT_REMOVE_PATH => 'optional',
PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
PCLZIP_OPT_ADD_PATH => 'optional',
PCLZIP_CB_PRE_EXTRACT => 'optional',
PCLZIP_CB_POST_EXTRACT => 'optional',
PCLZIP_OPT_SET_CHMOD => 'optional',
PCLZIP_OPT_REPLACE_NEWER => 'optional'
, PCLZIP_OPT_STOP_ON_ERROR => 'optional'
, PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
PCLZIP_OPT_TEMP_FILE_ON => 'optional',
PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
)
);
if ($v_result != 1) {
return 0;
}
// ----- Set the arguments
if (isset($v_options[PCLZIP_OPT_PATH])) {
$v_path = $v_options[PCLZIP_OPT_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
$v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
}
if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
}
if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
// ----- Check for '/' in last path char
if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
$v_path .= '/';
}
$v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
}
if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
$v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = false;
} else {
}
} // ----- Look for 2 args
// Here we need to support the first historic synopsis of the
// method.
else {
// ----- Get the first argument
$v_path = $v_arg_list[0];
// ----- Look for the optional second argument
if ($v_size == 2) {
$v_remove_path = $v_arg_list[1];
} else {
if ($v_size > 2) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
// ----- Return
return 0;
}
}
}
}
// ----- Trace
// ----- Trick
// Here I want to reuse extractByRule(), so I need to parse the $p_index
// with privParseOptions()
$v_arg_trick = array(PCLZIP_OPT_BY_INDEX, $p_index);
$v_options_trick = array();
$v_result = $this->privParseOptions(
$v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
array(PCLZIP_OPT_BY_INDEX => 'optional')
);
if ($v_result != 1) {
return 0;
}
$v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
// ----- Look for default option values
$this->privOptionDefaultThreshold($v_options);
// ----- Call the extracting fct
if (
($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1
) {
return (0);
}
// ----- Return
return $p_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function :
// delete([$p_option, $p_option_value, ...])
// Description :
// This method removes files from the archive.
// If no parameters are given, then all the archive is emptied.
// Parameters :
// None or optional arguments.
// Options :
// PCLZIP_OPT_BY_INDEX :
// PCLZIP_OPT_BY_NAME :
// PCLZIP_OPT_BY_EREG :
// PCLZIP_OPT_BY_PREG :
// Return Values :
// 0 on failure,
// The list of the files which are still present in the archive.
// (see PclZip::listContent() for list entry format)
// --------------------------------------------------------------------------------
function delete()
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Check archive
if (!$this->privCheckFormat()) {
return (0);
}
// ----- Set default values
$v_options = array();
// ----- Look for variable options arguments
$v_size = func_num_args();
// ----- Look for arguments
if ($v_size > 0) {
// ----- Get the arguments
$v_arg_list = func_get_args();
// ----- Parse the options
$v_result = $this->privParseOptions(
$v_arg_list, $v_size, $v_options,
array(PCLZIP_OPT_BY_NAME => 'optional',
PCLZIP_OPT_BY_EREG => 'optional',
PCLZIP_OPT_BY_PREG => 'optional',
PCLZIP_OPT_BY_INDEX => 'optional')
);
if ($v_result != 1) {
return 0;
}
}
// ----- Magic quotes trick
$this->privDisableMagicQuotes();
// ----- Call the delete fct
$v_list = array();
if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
$this->privSwapBackMagicQuotes();
unset($v_list);
return (0);
}
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : deleteByIndex()
// Description :
// ***** Deprecated *****
// delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
// --------------------------------------------------------------------------------
function deleteByIndex($p_index)
{
$p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
// ----- Return
return $p_list;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : properties()
// Description :
// This method gives the properties of the archive.
// The properties are :
// nb : Number of files in the archive
// comment : Comment associated with the archive file
// status : not_exist, ok
// Parameters :
// None
// Return Values :
// 0 on failure,
// An array with the archive properties.
// --------------------------------------------------------------------------------
function properties()
{
// ----- Reset the error handler
$this->privErrorReset();
// ----- Magic quotes trick
$this->privDisableMagicQuotes();
// ----- Check archive
if (!$this->privCheckFormat()) {
$this->privSwapBackMagicQuotes();
return (0);
}
// ----- Default properties
$v_prop = array();
$v_prop['comment'] = '';
$v_prop['nb'] = 0;
$v_prop['status'] = 'not_exist';
// ----- Look if file exists
if (@is_file($this->zipname)) {
// ----- Open the zip file
if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) {
$this->privSwapBackMagicQuotes();
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode'
);
// ----- Return
return 0;
}
// ----- Read the central directory informations
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
$this->privSwapBackMagicQuotes();
return 0;
}
// ----- Close the zip file
$this->privCloseFd();
// ----- Set the user attributes
$v_prop['comment'] = $v_central_dir['comment'];
$v_prop['nb'] = $v_central_dir['entries'];
$v_prop['status'] = 'ok';
}
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_prop;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : duplicate()
// Description :
// This method creates an archive by copying the content of an other one. If
// the archive already exist, it is replaced by the new one without any warning.
// Parameters :
// $p_archive : The filename of a valid archive, or
// a valid PclZip object.
// Return Values :
// 1 on success.
// 0 or a negative value on error (error code).
// --------------------------------------------------------------------------------
function duplicate($p_archive)
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Look if the $p_archive is a PclZip object
if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip')) {
// ----- Duplicate the archive
$v_result = $this->privDuplicate($p_archive->zipname);
} // ----- Look if the $p_archive is a string (so a filename)
else {
if (is_string($p_archive)) {
// ----- Check that $p_archive is a valid zip file
// TBC : Should also check the archive format
if (!is_file($p_archive)) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '" . $p_archive . "'");
$v_result = PCLZIP_ERR_MISSING_FILE;
} else {
// ----- Duplicate the archive
$v_result = $this->privDuplicate($p_archive);
}
} // ----- Invalid variable
else {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
$v_result = PCLZIP_ERR_INVALID_PARAMETER;
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : merge()
// Description :
// This method merge the $p_archive_to_add archive at the end of the current
// one ($this).
// If the archive ($this) does not exist, the merge becomes a duplicate.
// If the $p_archive_to_add archive does not exist, the merge is a success.
// Parameters :
// $p_archive_to_add : It can be directly the filename of a valid zip archive,
// or a PclZip object archive.
// Return Values :
// 1 on success,
// 0 or negative values on error (see below).
// --------------------------------------------------------------------------------
function merge($p_archive_to_add)
{
$v_result = 1;
// ----- Reset the error handler
$this->privErrorReset();
// ----- Check archive
if (!$this->privCheckFormat()) {
return (0);
}
// ----- Look if the $p_archive_to_add is a PclZip object
if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip')) {
// ----- Merge the archive
$v_result = $this->privMerge($p_archive_to_add);
} // ----- Look if the $p_archive_to_add is a string (so a filename)
else {
if (is_string($p_archive_to_add)) {
// ----- Create a temporary archive
$v_object_archive = new PclZip($p_archive_to_add);
// ----- Merge the archive
$v_result = $this->privMerge($v_object_archive);
} // ----- Invalid variable
else {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
$v_result = PCLZIP_ERR_INVALID_PARAMETER;
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : errorCode()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function errorCode()
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
return (PclErrorCode());
} else {
return ($this->error_code);
}
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : errorName()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function errorName($p_with_code = false)
{
$v_name = array(PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
, PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
, PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
);
if (isset($v_name[$this->error_code])) {
$v_value = $v_name[$this->error_code];
} else {
$v_value = 'NoName';
}
if ($p_with_code) {
return ($v_value . ' (' . $this->error_code . ')');
} else {
return ($v_value);
}
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : errorInfo()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function errorInfo($p_full = false)
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
return (PclErrorString());
} else {
if ($p_full) {
return ($this->errorName(true) . " : " . $this->error_string);
} else {
return ($this->error_string . " [code " . $this->error_code . "]");
}
}
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
// ***** *****
// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privCheckFormat()
// Description :
// This method check that the archive exists and is a valid zip archive.
// Several level of check exists. (futur)
// Parameters :
// $p_level : Level of check. Default 0.
// 0 : Check the first bytes (magic codes) (default value))
// 1 : 0 + Check the central directory (futur)
// 2 : 1 + Check each file header (futur)
// Return Values :
// true on success,
// false on error, the error code is set.
// --------------------------------------------------------------------------------
function privCheckFormat($p_level = 0)
{
$v_result = true;
// ----- Reset the file system cache
clearstatcache();
// ----- Reset the error handler
$this->privErrorReset();
// ----- Look if the file exits
if (!is_file($this->zipname)) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '" . $this->zipname . "'");
return (false);
}
// ----- Check that the file is readeable
if (!is_readable($this->zipname)) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '" . $this->zipname . "'");
return (false);
}
// ----- Check the magic code
// TBC
// ----- Check the central header
// TBC
// ----- Check each file header
// TBC
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privParseOptions()
// Description :
// This internal methods reads the variable list of arguments ($p_options_list,
// $p_size) and generate an array with the options and values ($v_result_list).
// $v_requested_options contains the options that can be present and those that
// must be present.
// $v_requested_options is an array, with the option value as key, and 'optional',
// or 'mandatory' as value.
// Parameters :
// See above.
// Return Values :
// 1 on success.
// 0 on failure.
// --------------------------------------------------------------------------------
function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options = false)
{
$v_result = 1;
// ----- Read the options
$i = 0;
while ($i < $p_size) {
// ----- Check if the option is supported
if (!isset($v_requested_options[$p_options_list[$i]])) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER,
"Invalid optional parameter '" . $p_options_list[$i] . "' for this method"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Look for next option
switch ($p_options_list[$i]) {
// ----- Look for options that request a path value
case PCLZIP_OPT_PATH :
case PCLZIP_OPT_REMOVE_PATH :
case PCLZIP_OPT_ADD_PATH :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
$v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i + 1], false);
$i++;
break;
case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
return PclZip::errorCode();
}
// ----- Check for incompatible options
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i])
. "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"
);
return PclZip::errorCode();
}
// ----- Check the value
$v_value = $p_options_list[$i + 1];
if ((!is_integer($v_value)) || ($v_value < 0)) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Integer expected for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
return PclZip::errorCode();
}
// ----- Get the value (and convert it in bytes)
$v_result_list[$p_options_list[$i]] = $v_value * 1048576;
$i++;
break;
case PCLZIP_OPT_TEMP_FILE_ON :
// ----- Check for incompatible options
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i])
. "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"
);
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = true;
break;
case PCLZIP_OPT_TEMP_FILE_OFF :
// ----- Check for incompatible options
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i])
. "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"
);
return PclZip::errorCode();
}
// ----- Check for incompatible options
if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER, "Option '" . PclZipUtilOptionText($p_options_list[$i])
. "' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"
);
return PclZip::errorCode();
}
$v_result_list[$p_options_list[$i]] = true;
break;
case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
if (is_string($p_options_list[$i + 1])
&& ($p_options_list[$i + 1] != '')
) {
$v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath(
$p_options_list[$i + 1], false
);
$i++;
} else {
}
break;
// ----- Look for options that request an array of string for value
case PCLZIP_OPT_BY_NAME :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
if (is_string($p_options_list[$i + 1])) {
$v_result_list[$p_options_list[$i]][0] = $p_options_list[$i + 1];
} else {
if (is_array($p_options_list[$i + 1])) {
$v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
} else {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
}
$i++;
break;
// ----- Look for options that request an EREG or PREG expression
case PCLZIP_OPT_BY_EREG :
// ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
// to PCLZIP_OPT_BY_PREG
$p_options_list[$i] = PCLZIP_OPT_BY_PREG;
case PCLZIP_OPT_BY_PREG :
//case PCLZIP_OPT_CRYPT :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
if (is_string($p_options_list[$i + 1])) {
$v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
} else {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Wrong parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
$i++;
break;
// ----- Look for options that takes a string
case PCLZIP_OPT_COMMENT :
case PCLZIP_OPT_ADD_COMMENT :
case PCLZIP_OPT_PREPEND_COMMENT :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '"
. PclZipUtilOptionText($p_options_list[$i])
. "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
if (is_string($p_options_list[$i + 1])) {
$v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
} else {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Wrong parameter value for option '"
. PclZipUtilOptionText($p_options_list[$i])
. "'"
);
// ----- Return
return PclZip::errorCode();
}
$i++;
break;
// ----- Look for options that request an array of index
case PCLZIP_OPT_BY_INDEX :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
$v_work_list = array();
if (is_string($p_options_list[$i + 1])) {
// ----- Remove spaces
$p_options_list[$i + 1] = strtr($p_options_list[$i + 1], ' ', '');
// ----- Parse items
$v_work_list = explode(",", $p_options_list[$i + 1]);
} else {
if (is_integer($p_options_list[$i + 1])) {
$v_work_list[0] = $p_options_list[$i + 1] . '-' . $p_options_list[$i + 1];
} else {
if (is_array($p_options_list[$i + 1])) {
$v_work_list = $p_options_list[$i + 1];
} else {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Value must be integer, string or array for option '" . PclZipUtilOptionText(
$p_options_list[$i]
) . "'"
);
// ----- Return
return PclZip::errorCode();
}
}
}
// ----- Reduce the index list
// each index item in the list must be a couple with a start and
// an end value : [0,3], [5-5], [8-10], ...
// ----- Check the format of each item
$v_sort_flag = false;
$v_sort_value = 0;
for ($j = 0; $j < sizeof($v_work_list); $j++) {
// ----- Explode the item
$v_item_list = explode("-", $v_work_list[$j]);
$v_size_item_list = sizeof($v_item_list);
// ----- TBC : Here we might check that each item is a
// real integer ...
// ----- Look for single value
if ($v_size_item_list == 1) {
// ----- Set the option value
$v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
$v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
} elseif ($v_size_item_list == 2) {
// ----- Set the option value
$v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
$v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
} else {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Too many values in index range for option '" . PclZipUtilOptionText(
$p_options_list[$i]
) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Look for list sort
if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
$v_sort_flag = true;
// ----- TBC : An automatic sort should be writen ...
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Invalid order of index range for option '" . PclZipUtilOptionText($p_options_list[$i])
. "'"
);
// ----- Return
return PclZip::errorCode();
}
$v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
}
// ----- Sort the items
if ($v_sort_flag) {
// TBC : To Be Completed
}
// ----- Next option
$i++;
break;
// ----- Look for options that request no value
case PCLZIP_OPT_REMOVE_ALL_PATH :
case PCLZIP_OPT_EXTRACT_AS_STRING :
case PCLZIP_OPT_NO_COMPRESSION :
case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
case PCLZIP_OPT_REPLACE_NEWER :
case PCLZIP_OPT_STOP_ON_ERROR :
$v_result_list[$p_options_list[$i]] = true;
break;
// ----- Look for options that request an octal value
case PCLZIP_OPT_SET_CHMOD :
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
$v_result_list[$p_options_list[$i]] = $p_options_list[$i + 1];
$i++;
break;
// ----- Look for options that request a call-back
case PCLZIP_CB_PRE_EXTRACT :
case PCLZIP_CB_POST_EXTRACT :
case PCLZIP_CB_PRE_ADD :
case PCLZIP_CB_POST_ADD :
/* for futur use
case PCLZIP_CB_PRE_DELETE :
case PCLZIP_CB_POST_DELETE :
case PCLZIP_CB_PRE_LIST :
case PCLZIP_CB_POST_LIST :
*/
// ----- Check the number of parameters
if (($i + 1) >= $p_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_OPTION_VALUE,
"Missing parameter value for option '" . PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Get the value
$v_function_name = $p_options_list[$i + 1];
// ----- Check that the value is a valid existing function
if (!function_exists($v_function_name)) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_OPTION_VALUE,
"Function '" . $v_function_name . "()' is not an existing function for option '"
. PclZipUtilOptionText($p_options_list[$i]) . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Set the attribute
$v_result_list[$p_options_list[$i]] = $v_function_name;
$i++;
break;
default :
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER,
"Unknown parameter '"
. $p_options_list[$i] . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Next options
$i++;
}
// ----- Look for mandatory options
if ($v_requested_options !== false) {
for (
$key = reset($v_requested_options); $key = key($v_requested_options); $key = next($v_requested_options)
) {
// ----- Look for mandatory option
if ($v_requested_options[$key] == 'mandatory') {
// ----- Look if present
if (!isset($v_result_list[$key])) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER,
"Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")"
);
// ----- Return
return PclZip::errorCode();
}
}
}
}
// ----- Look for default values
if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privOptionDefaultThreshold()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privOptionDefaultThreshold(&$p_options)
{
$v_result = 1;
if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
|| isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])
) {
return $v_result;
}
// ----- Get 'memory_limit' configuration value
$v_memory_limit = ini_get('memory_limit');
$v_memory_limit = trim($v_memory_limit);
$last = strtolower(substr($v_memory_limit, -1));
if ($last == 'g') //$v_memory_limit = $v_memory_limit*1024*1024*1024;
{
$v_memory_limit = $v_memory_limit * 1073741824;
}
if ($last == 'm') //$v_memory_limit = $v_memory_limit*1024*1024;
{
$v_memory_limit = $v_memory_limit * 1048576;
}
if ($last == 'k') {
$v_memory_limit = $v_memory_limit * 1024;
}
$p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit * PCLZIP_TEMPORARY_FILE_RATIO);
// ----- Sanity check : No threshold if value lower than 1M
if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privFileDescrParseAtt()
// Description :
// Parameters :
// Return Values :
// 1 on success.
// 0 on failure.
// --------------------------------------------------------------------------------
function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options = false)
{
$v_result = 1;
// ----- For each file in the list check the attributes
foreach ($p_file_list as $v_key => $v_value) {
// ----- Check if the option is supported
if (!isset($v_requested_options[$v_key])) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '" . $v_key . "' for this file"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Look for attribute
switch ($v_key) {
case PCLZIP_ATT_FILE_NAME :
if (!is_string($v_value)) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid type " . gettype($v_value) . ". String expected for attribute '"
. PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
$p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
if ($p_filedescr['filename'] == '') {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid empty filename for attribute '" . PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
break;
case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
if (!is_string($v_value)) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid type " . gettype($v_value) . ". String expected for attribute '"
. PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
$p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
if ($p_filedescr['new_short_name'] == '') {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid empty short filename for attribute '" . PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
break;
case PCLZIP_ATT_FILE_NEW_FULL_NAME :
if (!is_string($v_value)) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid type " . gettype($v_value) . ". String expected for attribute '"
. PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
$p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
if ($p_filedescr['new_full_name'] == '') {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid empty full filename for attribute '" . PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
break;
// ----- Look for options that takes a string
case PCLZIP_ATT_FILE_COMMENT :
if (!is_string($v_value)) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid type " . gettype($v_value) . ". String expected for attribute '"
. PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
$p_filedescr['comment'] = $v_value;
break;
case PCLZIP_ATT_FILE_MTIME :
if (!is_integer($v_value)) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE,
"Invalid type " . gettype($v_value) . ". Integer expected for attribute '"
. PclZipUtilOptionText($v_key) . "'"
);
return PclZip::errorCode();
}
$p_filedescr['mtime'] = $v_value;
break;
case PCLZIP_ATT_FILE_CONTENT :
$p_filedescr['content'] = $v_value;
break;
default :
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER,
"Unknown parameter '" . $v_key . "'"
);
// ----- Return
return PclZip::errorCode();
}
// ----- Look for mandatory options
if ($v_requested_options !== false) {
for (
$key = reset($v_requested_options); $key = key($v_requested_options);
$key = next($v_requested_options)
) {
// ----- Look for mandatory option
if ($v_requested_options[$key] == 'mandatory') {
// ----- Look if present
if (!isset($p_file_list[$key])) {
PclZip::privErrorLog(
PCLZIP_ERR_INVALID_PARAMETER,
"Missing mandatory parameter " . PclZipUtilOptionText($key) . "(" . $key . ")"
);
return PclZip::errorCode();
}
}
}
}
// end foreach
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privFileDescrExpand()
// Description :
// This method look for each item of the list to see if its a file, a folder
// or a string to be added as file. For any other type of files (link, other)
// just ignore the item.
// Then prepare the information that will be stored for that file.
// When its a folder, expand the folder with all the files that are in that
// folder (recursively).
// Parameters :
// Return Values :
// 1 on success.
// 0 on failure.
// --------------------------------------------------------------------------------
function privFileDescrExpand(&$p_filedescr_list, &$p_options)
{
$v_result = 1;
// ----- Create a result list
$v_result_list = array();
// ----- Look each entry
for ($i = 0; $i < sizeof($p_filedescr_list); $i++) {
// ----- Get filedescr
$v_descr = $p_filedescr_list[$i];
// ----- Reduce the filename
$v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
$v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
// ----- Look for real file or folder
if (file_exists($v_descr['filename'])) {
if (@is_file($v_descr['filename'])) {
$v_descr['type'] = 'file';
} else {
if (@is_dir($v_descr['filename'])) {
$v_descr['type'] = 'folder';
} else {
if (@is_link($v_descr['filename'])) {
// skip
continue;
} else {
// skip
continue;
}
}
}
} // ----- Look for string added as file
else {
if (isset($v_descr['content'])) {
$v_descr['type'] = 'virtual_file';
} // ----- Missing file
else {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '" . $v_descr['filename'] . "' does not exist");
// ----- Return
return PclZip::errorCode();
}
}
// ----- Calculate the stored filename
$this->privCalculateStoredFilename($v_descr, $p_options);
// ----- Add the descriptor in result list
$v_result_list[sizeof($v_result_list)] = $v_descr;
// ----- Look for folder
if ($v_descr['type'] == 'folder') {
// ----- List of items in folder
$v_dirlist_descr = array();
$v_dirlist_nb = 0;
if ($v_folder_handler = @opendir($v_descr['filename'])) {
while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
// ----- Skip '.' and '..'
if (($v_item_handler == '.') || ($v_item_handler == '..')) {
continue;
}
// ----- Compose the full filename
$v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'] . '/' . $v_item_handler;
// ----- Look for different stored filename
// Because the name of the folder was changed, the name of the
// files/sub-folders also change
if (($v_descr['stored_filename'] != $v_descr['filename'])
&& (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
) {
if ($v_descr['stored_filename'] != '') {
$v_dirlist_descr[$v_dirlist_nb]['new_full_name']
= $v_descr['stored_filename'] . '/' . $v_item_handler;
} else {
$v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
}
}
$v_dirlist_nb++;
}
@closedir($v_folder_handler);
} else {
// TBC : unable to open folder in read mode
}
// ----- Expand each element of the list
if ($v_dirlist_nb != 0) {
// ----- Expand
if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
return $v_result;
}
// ----- Concat the resulting list
$v_result_list = array_merge($v_result_list, $v_dirlist_descr);
} else {
}
// ----- Free local array
unset($v_dirlist_descr);
}
}
// ----- Get the result list
$p_filedescr_list = $v_result_list;
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privCreate()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result = 1;
$v_list_detail = array();
// ----- Magic quotes trick
$this->privDisableMagicQuotes();
// ----- Open the file in write mode
if (($v_result = $this->privOpenFd('wb')) != 1) {
// ----- Return
return $v_result;
}
// ----- Add the list of files
$v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
// ----- Close
$this->privCloseFd();
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAdd()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result = 1;
$v_list_detail = array();
// ----- Look if the archive exists or is empty
if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) {
// ----- Do a create
$v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
// ----- Return
return $v_result;
}
// ----- Magic quotes trick
$this->privDisableMagicQuotes();
// ----- Open the zip file
if (($v_result = $this->privOpenFd('rb')) != 1) {
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
// ----- Read the central directory informations
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Go to beginning of File
@rewind($this->zip_fd);
// ----- Creates a temporay file
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
// ----- Open the temporary file in write mode
if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL,
'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode'
);
// ----- Return
return PclZip::errorCode();
}
// ----- Copy the files from the archive to the temporary file
// TBC : Here I should better append the file and go back to erase the central dir
$v_size = $v_central_dir['offset'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($this->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Swap the file descriptor
// Here is a trick : I swap the temporary fd with the zip fd, in order to use
// the following methods on the temporary fil and not the real archive
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
// ----- Add the files
$v_header_list = array();
if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) {
fclose($v_zip_temp_fd);
$this->privCloseFd();
@unlink($v_zip_temp_name);
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
// ----- Store the offset of the central dir
$v_offset = @ftell($this->zip_fd);
// ----- Copy the block of file headers from the old archive
$v_size = $v_central_dir['size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_zip_temp_fd, $v_read_size);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Create the Central Dir files header
for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) {
// ----- Create the file header
if ($v_header_list[$i]['status'] == 'ok') {
if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
fclose($v_zip_temp_fd);
$this->privCloseFd();
@unlink($v_zip_temp_name);
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
$v_count++;
}
// ----- Transform the header to a 'usable' info
$this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
}
// ----- Zip file comment
$v_comment = $v_central_dir['comment'];
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
}
if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
$v_comment = $v_comment . $p_options[PCLZIP_OPT_ADD_COMMENT];
}
if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT] . $v_comment;
}
// ----- Calculate the size of the central header
$v_size = @ftell($this->zip_fd) - $v_offset;
// ----- Create the central dir footer
if ((
$v_result = $this->privWriteCentralHeader($v_count + $v_central_dir['entries'], $v_size, $v_offset, $v_comment))
!= 1
) {
// ----- Reset the file list
unset($v_header_list);
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
// ----- Swap back the file descriptor
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
// ----- Close
$this->privCloseFd();
// ----- Close the temporary file
@fclose($v_zip_temp_fd);
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Delete the zip file
// TBC : I should test the result ...
@unlink($this->zipname);
// ----- Rename the temporary file
// TBC : I should test the result ...
//@rename($v_zip_temp_name, $this->zipname);
PclZipUtilRename($v_zip_temp_name, $this->zipname);
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privOpenFd()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function privOpenFd($p_mode)
{
$v_result = 1;
// ----- Look if already open
if ($this->zip_fd != 0) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \'' . $this->zipname . '\' already open');
// ----- Return
return PclZip::errorCode();
}
// ----- Open the zip file
if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in ' . $p_mode . ' mode'
);
// ----- Return
return PclZip::errorCode();
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privCloseFd()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function privCloseFd()
{
$v_result = 1;
if ($this->zip_fd != 0) {
@fclose($this->zip_fd);
}
$this->zip_fd = 0;
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAddList()
// Description :
// $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
// different from the real path of the file. This is usefull if you want to have PclTar
// running in any directory, and memorize relative path from an other directory.
// Parameters :
// $p_list : An array containing the file or directory names to add in the tar
// $p_result_list : list of added files with their properties (specially the status field)
// $p_add_dir : Path to add in the filename path archived
// $p_remove_dir : Path to remove in the filename path archived
// Return Values :
// --------------------------------------------------------------------------------
// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result = 1;
// ----- Add the files
$v_header_list = array();
if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) {
// ----- Return
return $v_result;
}
// ----- Store the offset of the central dir
$v_offset = @ftell($this->zip_fd);
// ----- Create the Central Dir files header
for ($i = 0, $v_count = 0; $i < sizeof($v_header_list); $i++) {
// ----- Create the file header
if ($v_header_list[$i]['status'] == 'ok') {
if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
// ----- Return
return $v_result;
}
$v_count++;
}
// ----- Transform the header to a 'usable' info
$this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
}
// ----- Zip file comment
$v_comment = '';
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
}
// ----- Calculate the size of the central header
$v_size = @ftell($this->zip_fd) - $v_offset;
// ----- Create the central dir footer
if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) {
// ----- Reset the file list
unset($v_header_list);
// ----- Return
return $v_result;
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAddFileList()
// Description :
// Parameters :
// $p_filedescr_list : An array containing the file description
// or directory names to add in the zip
// $p_result_list : list of added files with their properties (specially the status field)
// Return Values :
// --------------------------------------------------------------------------------
function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
{
$v_result = 1;
$v_header = array();
// ----- Recuperate the current number of elt in list
$v_nb = sizeof($p_result_list);
// ----- Loop on the files
for ($j = 0; ($j < sizeof($p_filedescr_list)) && ($v_result == 1); $j++) {
// ----- Format the filename
$p_filedescr_list[$j]['filename']
= PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
// ----- Skip empty file names
// TBC : Can this be possible ? not checked in DescrParseAtt ?
if ($p_filedescr_list[$j]['filename'] == "") {
continue;
}
// ----- Check the filename
if (($p_filedescr_list[$j]['type'] != 'virtual_file')
&& (!file_exists($p_filedescr_list[$j]['filename']))
) {
PclZip::privErrorLog(
PCLZIP_ERR_MISSING_FILE, "File '" . $p_filedescr_list[$j]['filename'] . "' does not exist"
);
return PclZip::errorCode();
}
// ----- Look if it is a file or a dir with no all path remove option
// or a dir with all its path removed
// if ( (is_file($p_filedescr_list[$j]['filename']))
// || ( is_dir($p_filedescr_list[$j]['filename'])
if (($p_filedescr_list[$j]['type'] == 'file')
|| ($p_filedescr_list[$j]['type'] == 'virtual_file')
|| (($p_filedescr_list[$j]['type'] == 'folder')
&& (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
|| !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
) {
// ----- Add the file
$v_result = $this->privAddFile(
$p_filedescr_list[$j], $v_header,
$p_options
);
if ($v_result != 1) {
return $v_result;
}
// ----- Store the file infos
$p_result_list[$v_nb++] = $v_header;
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAddFile()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privAddFile($p_filedescr, &$p_header, &$p_options)
{
$v_result = 1;
// ----- Working variable
$p_filename = $p_filedescr['filename'];
// TBC : Already done in the fileAtt check ... ?
if ($p_filename == "") {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
// ----- Return
return PclZip::errorCode();
}
// ----- Look for a stored different filename
/* TBC : Removed
if (isset($p_filedescr['stored_filename'])) {
$v_stored_filename = $p_filedescr['stored_filename'];
}
else {
$v_stored_filename = $p_filedescr['stored_filename'];
}
*/
// ----- Set the file properties
clearstatcache();
$p_header['version'] = 20;
$p_header['version_extracted'] = 10;
$p_header['flag'] = 0;
$p_header['compression'] = 0;
$p_header['crc'] = 0;
$p_header['compressed_size'] = 0;
$p_header['filename_len'] = strlen($p_filename);
$p_header['extra_len'] = 0;
$p_header['disk'] = 0;
$p_header['internal'] = 0;
$p_header['offset'] = 0;
$p_header['filename'] = $p_filename;
// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
$p_header['stored_filename'] = $p_filedescr['stored_filename'];
$p_header['extra'] = '';
$p_header['status'] = 'ok';
$p_header['index'] = -1;
// ----- Look for regular file
if ($p_filedescr['type'] == 'file') {
$p_header['external'] = 0x00000000;
$p_header['size'] = filesize($p_filename);
} // ----- Look for regular folder
else {
if ($p_filedescr['type'] == 'folder') {
$p_header['external'] = 0x00000010;
$p_header['mtime'] = filemtime($p_filename);
$p_header['size'] = filesize($p_filename);
} // ----- Look for virtual file
else {
if ($p_filedescr['type'] == 'virtual_file') {
$p_header['external'] = 0x00000000;
$p_header['size'] = strlen($p_filedescr['content']);
}
}
}
// ----- Look for filetime
if (isset($p_filedescr['mtime'])) {
$p_header['mtime'] = $p_filedescr['mtime'];
} else {
if ($p_filedescr['type'] == 'virtual_file') {
$p_header['mtime'] = time();
} else {
$p_header['mtime'] = filemtime($p_filename);
}
}
// ------ Look for file comment
if (isset($p_filedescr['comment'])) {
$p_header['comment_len'] = strlen($p_filedescr['comment']);
$p_header['comment'] = $p_filedescr['comment'];
} else {
$p_header['comment_len'] = 0;
$p_header['comment'] = '';
}
// ----- Look for pre-add callback
if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
if ($v_result == 0) {
// ----- Change the file status
$p_header['status'] = "skipped";
$v_result = 1;
}
// ----- Update the informations
// Only some fields can be modified
if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
$p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
}
}
// ----- Look for empty stored filename
if ($p_header['stored_filename'] == "") {
$p_header['status'] = "filtered";
}
// ----- Check the path length
if (strlen($p_header['stored_filename']) > 0xFF) {
$p_header['status'] = 'filename_too_long';
}
// ----- Look if no error, or file not skipped
if ($p_header['status'] == 'ok') {
// ----- Look for a file
if ($p_filedescr['type'] == 'file') {
// ----- Look for using temporary file to zip
if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])))
) {
$v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
if ($v_result < PCLZIP_ERR_NO_ERROR) {
return $v_result;
}
} // ----- Use "in memory" zip algo
else {
// ----- Open the source file
if (($v_file = @fopen($p_filename, "rb")) == 0) {
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode"
);
return PclZip::errorCode();
}
// ----- Read the file content
$v_content = @fread($v_file, $p_header['size']);
// ----- Close the file
@fclose($v_file);
// ----- Calculate the CRC
$p_header['crc'] = @crc32($v_content);
// ----- Look for no compression
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
// ----- Set header parameters
$p_header['compressed_size'] = $p_header['size'];
$p_header['compression'] = 0;
} // ----- Look for normal compression
else {
// ----- Compress the content
$v_content = @gzdeflate($v_content);
// ----- Set header parameters
$p_header['compressed_size'] = strlen($v_content);
$p_header['compression'] = 8;
}
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
@fclose($v_file);
return $v_result;
}
// ----- Write the compressed (or not) content
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
}
} // ----- Look for a virtual file (a file from string)
else {
if ($p_filedescr['type'] == 'virtual_file') {
$v_content = $p_filedescr['content'];
// ----- Calculate the CRC
$p_header['crc'] = @crc32($v_content);
// ----- Look for no compression
if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
// ----- Set header parameters
$p_header['compressed_size'] = $p_header['size'];
$p_header['compression'] = 0;
} // ----- Look for normal compression
else {
// ----- Compress the content
$v_content = @gzdeflate($v_content);
// ----- Set header parameters
$p_header['compressed_size'] = strlen($v_content);
$p_header['compression'] = 8;
}
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
@fclose($v_file);
return $v_result;
}
// ----- Write the compressed (or not) content
@fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
} // ----- Look for a directory
else {
if ($p_filedescr['type'] == 'folder') {
// ----- Look for directory last '/'
if (@substr($p_header['stored_filename'], -1) != '/') {
$p_header['stored_filename'] .= '/';
}
// ----- Set the file properties
$p_header['size'] = 0;
//$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
$p_header['external'] = 0x00000010; // Value for a folder : to be checked
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
return $v_result;
}
}
}
}
}
// ----- Look for post-add callback
if (isset($p_options[PCLZIP_CB_POST_ADD])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_header, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
if ($v_result == 0) {
// ----- Ignored
$v_result = 1;
}
// ----- Update the informations
// Nothing can be modified
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privAddFileUsingTempFile()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
{
$v_result = PCLZIP_ERR_NO_ERROR;
// ----- Working variable
$p_filename = $p_filedescr['filename'];
// ----- Open the source file
if (($v_file = @fopen($p_filename, "rb")) == 0) {
PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
return PclZip::errorCode();
}
// ----- Creates a compressed temporary file
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz';
if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
fclose($v_file);
PclZip::privErrorLog(
PCLZIP_ERR_WRITE_OPEN_FAIL,
'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode'
);
return PclZip::errorCode();
}
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
$v_size = filesize($p_filename);
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_file, $v_read_size);
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@gzputs($v_file_compressed, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Close the file
@fclose($v_file);
@gzclose($v_file_compressed);
// ----- Check the minimum file size
if (filesize($v_gzip_temp_name) < 18) {
PclZip::privErrorLog(
PCLZIP_ERR_BAD_FORMAT,
'gzip temporary file \'' . $v_gzip_temp_name . '\' has invalid filesize - should be minimum 18 bytes'
);
return PclZip::errorCode();
}
// ----- Extract the compressed attributes
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL,
'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode'
);
return PclZip::errorCode();
}
// ----- Read the gzip file header
$v_binary_data = @fread($v_file_compressed, 10);
$v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
// ----- Check some parameters
$v_data_header['os'] = bin2hex($v_data_header['os']);
// ----- Read the gzip file footer
@fseek($v_file_compressed, filesize($v_gzip_temp_name) - 8);
$v_binary_data = @fread($v_file_compressed, 8);
$v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
// ----- Set the attributes
$p_header['compression'] = ord($v_data_header['cm']);
//$p_header['mtime'] = $v_data_header['mtime'];
$p_header['crc'] = $v_data_footer['crc'];
$p_header['compressed_size'] = filesize($v_gzip_temp_name) - 18;
// ----- Close the file
@fclose($v_file_compressed);
// ----- Call the header generation
if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
return $v_result;
}
// ----- Add the compressed data
if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL,
'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode'
);
return PclZip::errorCode();
}
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
fseek($v_file_compressed, 10);
$v_size = $p_header['compressed_size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($v_file_compressed, $v_read_size);
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Close the file
@fclose($v_file_compressed);
// ----- Unlink the temporary file
@unlink($v_gzip_temp_name);
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privCalculateStoredFilename()
// Description :
// Based on file descriptor properties and global options, this method
// calculate the filename that will be stored in the archive.
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privCalculateStoredFilename(&$p_filedescr, &$p_options)
{
$v_result = 1;
// ----- Working variables
$p_filename = $p_filedescr['filename'];
if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
$p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
} else {
$p_add_dir = '';
}
if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
$p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
} else {
$p_remove_dir = '';
}
if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
$p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
} else {
$p_remove_all_dir = 0;
}
// ----- Look for full name change
if (isset($p_filedescr['new_full_name'])) {
// ----- Remove drive letter if any
$v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
} // ----- Look for path and/or short name change
else {
// ----- Look for short name change
// Its when we cahnge just the filename but not the path
if (isset($p_filedescr['new_short_name'])) {
$v_path_info = pathinfo($p_filename);
$v_dir = '';
if ($v_path_info['dirname'] != '') {
$v_dir = $v_path_info['dirname'] . '/';
}
$v_stored_filename = $v_dir . $p_filedescr['new_short_name'];
} else {
// ----- Calculate the stored filename
$v_stored_filename = $p_filename;
}
// ----- Look for all path to remove
if ($p_remove_all_dir) {
$v_stored_filename = basename($p_filename);
} // ----- Look for partial path remove
else {
if ($p_remove_dir != "") {
if (substr($p_remove_dir, -1) != '/') {
$p_remove_dir .= "/";
}
if ((substr($p_filename, 0, 2) == "./")
|| (substr($p_remove_dir, 0, 2) == "./")
) {
if ((substr($p_filename, 0, 2) == "./")
&& (substr($p_remove_dir, 0, 2) != "./")
) {
$p_remove_dir = "./" . $p_remove_dir;
}
if ((substr($p_filename, 0, 2) != "./")
&& (substr($p_remove_dir, 0, 2) == "./")
) {
$p_remove_dir = substr($p_remove_dir, 2);
}
}
$v_compare = PclZipUtilPathInclusion(
$p_remove_dir,
$v_stored_filename
);
if ($v_compare > 0) {
if ($v_compare == 2) {
$v_stored_filename = "";
} else {
$v_stored_filename = substr(
$v_stored_filename,
strlen($p_remove_dir)
);
}
}
}
}
// ----- Remove drive letter if any
$v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
// ----- Look for path to add
if ($p_add_dir != "") {
if (substr($p_add_dir, -1) == "/") {
$v_stored_filename = $p_add_dir . $v_stored_filename;
} else {
$v_stored_filename = $p_add_dir . "/" . $v_stored_filename;
}
}
}
// ----- Filename (reduce the path of stored name)
$v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
$p_filedescr['stored_filename'] = $v_stored_filename;
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privWriteFileHeader()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privWriteFileHeader(&$p_header)
{
$v_result = 1;
// ----- Store the offset position of the file
$p_header['offset'] = ftell($this->zip_fd);
// ----- Transform UNIX mtime to DOS format mdate/mtime
$v_date = getdate($p_header['mtime']);
$v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2;
$v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday'];
// ----- Packed data
$v_binary_data = pack(
"VvvvvvVVVvv", 0x04034b50,
$p_header['version_extracted'], $p_header['flag'],
$p_header['compression'], $v_mtime, $v_mdate,
$p_header['crc'], $p_header['compressed_size'],
$p_header['size'],
strlen($p_header['stored_filename']),
$p_header['extra_len']
);
// ----- Write the first 148 bytes of the header in the archive
fputs($this->zip_fd, $v_binary_data, 30);
// ----- Write the variable fields
if (strlen($p_header['stored_filename']) != 0) {
fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
}
if ($p_header['extra_len'] != 0) {
fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privWriteCentralFileHeader()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privWriteCentralFileHeader(&$p_header)
{
$v_result = 1;
// TBC
//for(reset($p_header); $key = key($p_header); next($p_header)) {
//}
// ----- Transform UNIX mtime to DOS format mdate/mtime
$v_date = getdate($p_header['mtime']);
$v_mtime = ($v_date['hours'] << 11) + ($v_date['minutes'] << 5) + $v_date['seconds'] / 2;
$v_mdate = (($v_date['year'] - 1980) << 9) + ($v_date['mon'] << 5) + $v_date['mday'];
// ----- Packed data
$v_binary_data = pack(
"VvvvvvvVVVvvvvvVV", 0x02014b50,
$p_header['version'], $p_header['version_extracted'],
$p_header['flag'], $p_header['compression'],
$v_mtime, $v_mdate, $p_header['crc'],
$p_header['compressed_size'], $p_header['size'],
strlen($p_header['stored_filename']),
$p_header['extra_len'], $p_header['comment_len'],
$p_header['disk'], $p_header['internal'],
$p_header['external'], $p_header['offset']
);
// ----- Write the 42 bytes of the header in the zip file
fputs($this->zip_fd, $v_binary_data, 46);
// ----- Write the variable fields
if (strlen($p_header['stored_filename']) != 0) {
fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
}
if ($p_header['extra_len'] != 0) {
fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
}
if ($p_header['comment_len'] != 0) {
fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privWriteCentralHeader()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
{
$v_result = 1;
// ----- Packed data
$v_binary_data = pack(
"VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
$p_nb_entries, $p_size,
$p_offset, strlen($p_comment)
);
// ----- Write the 22 bytes of the header in the zip file
fputs($this->zip_fd, $v_binary_data, 22);
// ----- Write the variable fields
if (strlen($p_comment) != 0) {
fputs($this->zip_fd, $p_comment, strlen($p_comment));
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privList()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privList(&$p_list)
{
$v_result = 1;
// ----- Magic quotes trick
$this->privDisableMagicQuotes();
// ----- Open the zip file
if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0) {
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \'' . $this->zipname . '\' in binary read mode'
);
// ----- Return
return PclZip::errorCode();
}
// ----- Read the central directory informations
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Go to beginning of Central Dir
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_central_dir['offset'])) {
$this->privSwapBackMagicQuotes();
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
// ----- Return
return PclZip::errorCode();
}
// ----- Read each entry
for ($i = 0; $i < $v_central_dir['entries']; $i++) {
// ----- Read the file header
if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) {
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_header['index'] = $i;
// ----- Get the only interesting attributes
$this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
unset($v_header);
}
// ----- Close the zip file
$this->privCloseFd();
// ----- Magic quotes trick
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privConvertHeader2FileInfo()
// Description :
// This function takes the file informations from the central directory
// entries and extract the interesting parameters that will be given back.
// The resulting file infos are set in the array $p_info
// $p_info['filename'] : Filename with full path. Given by user (add),
// extracted in the filesystem (extract).
// $p_info['stored_filename'] : Stored filename in the archive.
// $p_info['size'] = Size of the file.
// $p_info['compressed_size'] = Compressed size of the file.
// $p_info['mtime'] = Last modification date of the file.
// $p_info['comment'] = Comment associated with the file.
// $p_info['folder'] = true/false : indicates if the entry is a folder or not.
// $p_info['status'] = status of the action on the file.
// $p_info['crc'] = CRC of the file content.
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privConvertHeader2FileInfo($p_header, &$p_info)
{
$v_result = 1;
// ----- Get the interesting attributes
$v_temp_path = PclZipUtilPathReduction($p_header['filename']);
$p_info['filename'] = $v_temp_path;
$v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
$p_info['stored_filename'] = $v_temp_path;
$p_info['size'] = $p_header['size'];
$p_info['compressed_size'] = $p_header['compressed_size'];
$p_info['mtime'] = $p_header['mtime'];
$p_info['comment'] = $p_header['comment'];
$p_info['folder'] = (($p_header['external'] & 0x00000010) == 0x00000010);
$p_info['index'] = $p_header['index'];
$p_info['status'] = $p_header['status'];
$p_info['crc'] = $p_header['crc'];
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privExtractByRule()
// Description :
// Extract a file or directory depending of rules (by index, by name, ...)
// Parameters :
// $p_file_list : An array where will be placed the properties of each
// extracted file
// $p_path : Path to add while writing the extracted files
// $p_remove_path : Path to remove (from the file memorized path) while writing the
// extracted files. If the path does not match the file path,
// the file is extracted with its memorized path.
// $p_remove_path does not apply to 'list' mode.
// $p_path and $p_remove_path are commulative.
// Return Values :
// 1 on success,0 or less on error (see error code list)
// --------------------------------------------------------------------------------
function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
{
$v_result = 1;
// ----- Magic quotes trick
$this->privDisableMagicQuotes();
// ----- Check the path
if (($p_path == "")
|| ((substr($p_path, 0, 1) != "/")
&& (substr($p_path, 0, 3) != "../")
&& (substr($p_path, 1, 2) != ":/"))
) {
$p_path = "./" . $p_path;
}
// ----- Reduce the path last (and duplicated) '/'
if (($p_path != "./") && ($p_path != "/")) {
// ----- Look for the path end '/'
while (substr($p_path, -1) == "/") {
$p_path = substr($p_path, 0, strlen($p_path) - 1);
}
}
// ----- Look for path to remove format (should end by /)
if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) {
$p_remove_path .= '/';
}
$p_remove_path_size = strlen($p_remove_path);
// ----- Open the zip file
if (($v_result = $this->privOpenFd('rb')) != 1) {
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Read the central directory informations
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Start at beginning of Central Dir
$v_pos_entry = $v_central_dir['offset'];
// ----- Read each entry
$j_start = 0;
for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
// ----- Read next Central dir entry
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_pos_entry)) {
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
// ----- Return
return PclZip::errorCode();
}
// ----- Read the file header
$v_header = array();
if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) {
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Store the index
$v_header['index'] = $i;
// ----- Store the file position
$v_pos_entry = ftell($this->zip_fd);
// ----- Look for the specific extract rules
$v_extract = false;
// ----- Look for extract by name rule
if ((isset($p_options[PCLZIP_OPT_BY_NAME]))
&& ($p_options[PCLZIP_OPT_BY_NAME] != 0)
) {
// ----- Look if the filename is in the list
for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
// ----- Look for a directory
if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
// ----- Look if the directory is in the filename path
if ((strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
&& (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
== $p_options[PCLZIP_OPT_BY_NAME][$j])
) {
$v_extract = true;
}
} // ----- Look for a filename
elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
$v_extract = true;
}
}
} // ----- Look for extract by ereg rule
// ereg() is deprecated with PHP 5.3
/*
else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
&& ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
$v_extract = true;
}
}
*/
// ----- Look for extract by preg rule
else {
if ((isset($p_options[PCLZIP_OPT_BY_PREG]))
&& ($p_options[PCLZIP_OPT_BY_PREG] != "")
) {
if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
$v_extract = true;
}
} // ----- Look for extract by index rule
else {
if ((isset($p_options[PCLZIP_OPT_BY_INDEX]))
&& ($p_options[PCLZIP_OPT_BY_INDEX] != 0)
) {
// ----- Look if the index is in the list
for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start'])
&& ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])
) {
$v_extract = true;
}
if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
$j_start = $j + 1;
}
if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {
break;
}
}
} // ----- Look for no rule, which means extract all the archive
else {
$v_extract = true;
}
}
}
// ----- Check compression method
if (($v_extract)
&& (($v_header['compression'] != 8)
&& ($v_header['compression'] != 0))
) {
$v_header['status'] = 'unsupported_compression';
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)
) {
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(
PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
"Filename '" . $v_header['stored_filename'] . "' is "
. "compressed by an unsupported compression "
. "method (" . $v_header['compression'] . ") "
);
return PclZip::errorCode();
}
}
// ----- Check encrypted files
if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
$v_header['status'] = 'unsupported_encryption';
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)
) {
$this->privSwapBackMagicQuotes();
PclZip::privErrorLog(
PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
"Unsupported encryption for "
. " filename '" . $v_header['stored_filename']
. "'"
);
return PclZip::errorCode();
}
}
// ----- Look for real extraction
if (($v_extract) && ($v_header['status'] != 'ok')) {
$v_result = $this->privConvertHeader2FileInfo(
$v_header,
$p_file_list[$v_nb_extracted++]
);
if ($v_result != 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
$v_extract = false;
}
// ----- Look for real extraction
if ($v_extract) {
// ----- Go to the file position
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_header['offset'])) {
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
// ----- Return
return PclZip::errorCode();
}
// ----- Look for extraction as string
if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
$v_string = '';
// ----- Extracting the file
$v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
if ($v_result1 < 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result1;
}
// ----- Get the only interesting attributes
if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1
) {
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Set the file content
$p_file_list[$v_nb_extracted]['content'] = $v_string;
// ----- Next extracted file
$v_nb_extracted++;
// ----- Look for user callback abort
if ($v_result1 == 2) {
break;
}
} // ----- Look for extraction in standard output
elseif ((isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
&& ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])
) {
// ----- Extracting the file in standard output
$v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
if ($v_result1 < 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result1;
}
// ----- Get the only interesting attributes
if (
($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1
) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Look for user callback abort
if ($v_result1 == 2) {
break;
}
} // ----- Look for normal extraction
else {
// ----- Extracting the file
$v_result1 = $this->privExtractFile(
$v_header,
$p_path, $p_remove_path,
$p_remove_all_path,
$p_options
);
if ($v_result1 < 1) {
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result1;
}
// ----- Get the only interesting attributes
if (
($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1
) {
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
return $v_result;
}
// ----- Look for user callback abort
if ($v_result1 == 2) {
break;
}
}
}
}
// ----- Close the zip file
$this->privCloseFd();
$this->privSwapBackMagicQuotes();
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privExtractFile()
// Description :
// Parameters :
// Return Values :
//
// 1 : ... ?
// PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
// --------------------------------------------------------------------------------
function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
{
$v_result = 1;
// ----- Read the file header
if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
// ----- Return
return $v_result;
}
// ----- Check that the file header is coherent with $p_entry info
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
// TBC
}
// ----- Look for all path to remove
if ($p_remove_all_path == true) {
// ----- Look for folder entry that not need to be extracted
if (($p_entry['external'] & 0x00000010) == 0x00000010) {
$p_entry['status'] = "filtered";
return $v_result;
}
// ----- Get the basename of the path
$p_entry['filename'] = basename($p_entry['filename']);
} // ----- Look for path to remove
else {
if ($p_remove_path != "") {
if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2) {
// ----- Change the file status
$p_entry['status'] = "filtered";
// ----- Return
return $v_result;
}
$p_remove_path_size = strlen($p_remove_path);
if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path) {
// ----- Remove the path
$p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
}
}
}
// ----- Add the path
if ($p_path != '') {
$p_entry['filename'] = $p_path . "/" . $p_entry['filename'];
}
// ----- Check a base_dir_restriction
if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
$v_inclusion
= PclZipUtilPathInclusion(
$p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
$p_entry['filename']
);
if ($v_inclusion == 0) {
PclZip::privErrorLog(
PCLZIP_ERR_DIRECTORY_RESTRICTION,
"Filename '" . $p_entry['filename'] . "' is "
. "outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"
);
return PclZip::errorCode();
}
}
// ----- Look for pre-extract callback
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
if ($v_result == 0) {
// ----- Change the file status
$p_entry['status'] = "skipped";
$v_result = 1;
}
// ----- Look for abort result
if ($v_result == 2) {
// ----- This status is internal and will be changed in 'skipped'
$p_entry['status'] = "aborted";
$v_result = PCLZIP_ERR_USER_ABORTED;
}
// ----- Update the informations
// Only some fields can be modified
$p_entry['filename'] = $v_local_header['filename'];
}
// ----- Look if extraction should be done
if ($p_entry['status'] == 'ok') {
// ----- Look for specific actions while the file exist
if (file_exists($p_entry['filename'])) {
// ----- Look if file is a directory
if (is_dir($p_entry['filename'])) {
// ----- Change the file status
$p_entry['status'] = "already_a_directory";
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
// For historical reason first PclZip implementation does not stop
// when this kind of error occurs.
if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)
) {
PclZip::privErrorLog(
PCLZIP_ERR_ALREADY_A_DIRECTORY,
"Filename '" . $p_entry['filename'] . "' is "
. "already used by an existing directory"
);
return PclZip::errorCode();
}
} // ----- Look if file is write protected
else {
if (!is_writeable($p_entry['filename'])) {
// ----- Change the file status
$p_entry['status'] = "write_protected";
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
// For historical reason first PclZip implementation does not stop
// when this kind of error occurs.
if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)
) {
PclZip::privErrorLog(
PCLZIP_ERR_WRITE_OPEN_FAIL,
"Filename '" . $p_entry['filename'] . "' exists "
. "and is write protected"
);
return PclZip::errorCode();
}
} // ----- Look if the extracted file is older
else {
if (filemtime($p_entry['filename']) > $p_entry['mtime']) {
// ----- Change the file status
if ((isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
&& ($p_options[PCLZIP_OPT_REPLACE_NEWER] === true)
) {
} else {
$p_entry['status'] = "newer_exist";
// ----- Look for PCLZIP_OPT_STOP_ON_ERROR
// For historical reason first PclZip implementation does not stop
// when this kind of error occurs.
if ((isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
&& ($p_options[PCLZIP_OPT_STOP_ON_ERROR] === true)
) {
PclZip::privErrorLog(
PCLZIP_ERR_WRITE_OPEN_FAIL,
"Newer version of '" . $p_entry['filename'] . "' exists "
. "and option PCLZIP_OPT_REPLACE_NEWER is not selected"
);
return PclZip::errorCode();
}
}
} else {
}
}
}
} // ----- Check the directory availability and create it if necessary
else {
if ((($p_entry['external'] & 0x00000010) == 0x00000010) || (substr($p_entry['filename'], -1) == '/')) {
$v_dir_to_check = $p_entry['filename'];
} else {
if (!strstr($p_entry['filename'], "/")) {
$v_dir_to_check = "";
} else {
$v_dir_to_check = dirname($p_entry['filename']);
}
}
if ((
$v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external'] & 0x00000010) == 0x00000010)))
!= 1
) {
// ----- Change the file status
$p_entry['status'] = "path_creation_fail";
// ----- Return
//return $v_result;
$v_result = 1;
}
}
}
// ----- Look if extraction should be done
if ($p_entry['status'] == 'ok') {
// ----- Do the extraction (if not a folder)
if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
// ----- Look for not compressed file
if ($p_entry['compression'] == 0) {
// ----- Opening destination file
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
// ----- Change the file status
$p_entry['status'] = "write_error";
// ----- Return
return $v_result;
}
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
$v_size = $p_entry['compressed_size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($this->zip_fd, $v_read_size);
/* Try to speed up the code
$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@fwrite($v_dest_file, $v_binary_data, $v_read_size);
*/
@fwrite($v_dest_file, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Closing the destination file
fclose($v_dest_file);
// ----- Change the file mtime
touch($p_entry['filename'], $p_entry['mtime']);
} else {
// ----- TBC
// Need to be finished
if (($p_entry['flag'] & 1) == 1) {
PclZip::privErrorLog(
PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
'File \'' . $p_entry['filename'] . '\' is encrypted. Encrypted files are not supported.'
);
return PclZip::errorCode();
}
// ----- Look for using temporary file to unzip
if ((!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
&& (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
|| (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
&& ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])))
) {
$v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
if ($v_result < PCLZIP_ERR_NO_ERROR) {
return $v_result;
}
} // ----- Look for extract in memory
else {
// ----- Read the compressed file in a buffer (one shot)
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
// ----- Decompress the file
$v_file_content = @gzinflate($v_buffer);
unset($v_buffer);
if ($v_file_content === false) {
// ----- Change the file status
// TBC
$p_entry['status'] = "error";
return $v_result;
}
// ----- Opening destination file
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
// ----- Change the file status
$p_entry['status'] = "write_error";
return $v_result;
}
// ----- Write the uncompressed data
@fwrite($v_dest_file, $v_file_content, $p_entry['size']);
unset($v_file_content);
// ----- Closing the destination file
@fclose($v_dest_file);
}
// ----- Change the file mtime
@touch($p_entry['filename'], $p_entry['mtime']);
}
// ----- Look for chmod option
if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
// ----- Change the mode of the file
@chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
}
}
}
// ----- Change abort status
if ($p_entry['status'] == "aborted") {
$p_entry['status'] = "skipped";
} // ----- Look for post-extract callback
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
// ----- Look for abort result
if ($v_result == 2) {
$v_result = PCLZIP_ERR_USER_ABORTED;
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privExtractFileUsingTempFile()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privExtractFileUsingTempFile(&$p_entry, &$p_options)
{
$v_result = 1;
// ----- Creates a temporary file
$v_gzip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.gz';
if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
fclose($v_file);
PclZip::privErrorLog(
PCLZIP_ERR_WRITE_OPEN_FAIL,
'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary write mode'
);
return PclZip::errorCode();
}
// ----- Write gz file format header
$v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
@fwrite($v_dest_file, $v_binary_data, 10);
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
$v_size = $p_entry['compressed_size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($this->zip_fd, $v_read_size);
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@fwrite($v_dest_file, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Write gz file format footer
$v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
@fwrite($v_dest_file, $v_binary_data, 8);
// ----- Close the temporary file
@fclose($v_dest_file);
// ----- Opening destination file
if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
$p_entry['status'] = "write_error";
return $v_result;
}
// ----- Open the temporary gz file
if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
@fclose($v_dest_file);
$p_entry['status'] = "read_error";
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL,
'Unable to open temporary file \'' . $v_gzip_temp_name . '\' in binary read mode'
);
return PclZip::errorCode();
}
// ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
$v_size = $p_entry['size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @gzread($v_src_file, $v_read_size);
//$v_binary_data = pack('a'.$v_read_size, $v_buffer);
@fwrite($v_dest_file, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
@fclose($v_dest_file);
@gzclose($v_src_file);
// ----- Delete the temporary file
@unlink($v_gzip_temp_name);
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privExtractFileInOutput()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privExtractFileInOutput(&$p_entry, &$p_options)
{
$v_result = 1;
// ----- Read the file header
if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
return $v_result;
}
// ----- Check that the file header is coherent with $p_entry info
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
// TBC
}
// ----- Look for pre-extract callback
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
if ($v_result == 0) {
// ----- Change the file status
$p_entry['status'] = "skipped";
$v_result = 1;
}
// ----- Look for abort result
if ($v_result == 2) {
// ----- This status is internal and will be changed in 'skipped'
$p_entry['status'] = "aborted";
$v_result = PCLZIP_ERR_USER_ABORTED;
}
// ----- Update the informations
// Only some fields can be modified
$p_entry['filename'] = $v_local_header['filename'];
}
// ----- Trace
// ----- Look if extraction should be done
if ($p_entry['status'] == 'ok') {
// ----- Do the extraction (if not a folder)
if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
// ----- Look for not compressed file
if ($p_entry['compressed_size'] == $p_entry['size']) {
// ----- Read the file in a buffer (one shot)
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
// ----- Send the file to the output
echo $v_buffer;
unset($v_buffer);
} else {
// ----- Read the compressed file in a buffer (one shot)
$v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
// ----- Decompress the file
$v_file_content = gzinflate($v_buffer);
unset($v_buffer);
// ----- Send the file to the output
echo $v_file_content;
unset($v_file_content);
}
}
}
// ----- Change abort status
if ($p_entry['status'] == "aborted") {
$p_entry['status'] = "skipped";
} // ----- Look for post-extract callback
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
// ----- Look for abort result
if ($v_result == 2) {
$v_result = PCLZIP_ERR_USER_ABORTED;
}
}
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privExtractFileAsString()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
{
$v_result = 1;
// ----- Read the file header
$v_header = array();
if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
// ----- Return
return $v_result;
}
// ----- Check that the file header is coherent with $p_entry info
if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
// TBC
}
// ----- Look for pre-extract callback
if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
if ($v_result == 0) {
// ----- Change the file status
$p_entry['status'] = "skipped";
$v_result = 1;
}
// ----- Look for abort result
if ($v_result == 2) {
// ----- This status is internal and will be changed in 'skipped'
$p_entry['status'] = "aborted";
$v_result = PCLZIP_ERR_USER_ABORTED;
}
// ----- Update the informations
// Only some fields can be modified
$p_entry['filename'] = $v_local_header['filename'];
}
// ----- Look if extraction should be done
if ($p_entry['status'] == 'ok') {
// ----- Do the extraction (if not a folder)
if (!(($p_entry['external'] & 0x00000010) == 0x00000010)) {
// ----- Look for not compressed file
// if ($p_entry['compressed_size'] == $p_entry['size'])
if ($p_entry['compression'] == 0) {
// ----- Reading the file
$p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
} else {
// ----- Reading the file
$v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
// ----- Decompress the file
if (($p_string = @gzinflate($v_data)) === false) {
// TBC
}
}
// ----- Trace
} else {
// TBC : error : can not extract a folder in a string
}
}
// ----- Change abort status
if ($p_entry['status'] == "aborted") {
$p_entry['status'] = "skipped";
} // ----- Look for post-extract callback
elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
// ----- Generate a local information
$v_local_header = array();
$this->privConvertHeader2FileInfo($p_entry, $v_local_header);
// ----- Swap the content to header
$v_local_header['content'] = $p_string;
$p_string = '';
// ----- Call the callback
// Here I do not use call_user_func() because I need to send a reference to the
// header.
// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
$v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
// ----- Swap back the content to header
$p_string = $v_local_header['content'];
unset($v_local_header['content']);
// ----- Look for abort result
if ($v_result == 2) {
$v_result = PCLZIP_ERR_USER_ABORTED;
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privReadFileHeader()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privReadFileHeader(&$p_header)
{
$v_result = 1;
// ----- Read the 4 bytes signature
$v_binary_data = @fread($this->zip_fd, 4);
$v_data = unpack('Vid', $v_binary_data);
// ----- Check signature
if ($v_data['id'] != 0x04034b50) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
// ----- Return
return PclZip::errorCode();
}
// ----- Read the first 42 bytes of the header
$v_binary_data = fread($this->zip_fd, 26);
// ----- Look for invalid block size
if (strlen($v_binary_data) != 26) {
$p_header['filename'] = "";
$p_header['status'] = "invalid_header";
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
// ----- Return
return PclZip::errorCode();
}
// ----- Extract the values
$v_data = unpack(
'vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len',
$v_binary_data
);
// ----- Get filename
$p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
// ----- Get extra_fields
if ($v_data['extra_len'] != 0) {
$p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
} else {
$p_header['extra'] = '';
}
// ----- Extract properties
$p_header['version_extracted'] = $v_data['version'];
$p_header['compression'] = $v_data['compression'];
$p_header['size'] = $v_data['size'];
$p_header['compressed_size'] = $v_data['compressed_size'];
$p_header['crc'] = $v_data['crc'];
$p_header['flag'] = $v_data['flag'];
$p_header['filename_len'] = $v_data['filename_len'];
// ----- Recuperate date in UNIX format
$p_header['mdate'] = $v_data['mdate'];
$p_header['mtime'] = $v_data['mtime'];
if ($p_header['mdate'] && $p_header['mtime']) {
// ----- Extract time
$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
$v_seconde = ($p_header['mtime'] & 0x001F) * 2;
// ----- Extract date
$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
$v_day = $p_header['mdate'] & 0x001F;
// ----- Get UNIX date format
$p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
} else {
$p_header['mtime'] = time();
}
// TBC
//for(reset($v_data); $key = key($v_data); next($v_data)) {
//}
// ----- Set the stored filename
$p_header['stored_filename'] = $p_header['filename'];
// ----- Set the status field
$p_header['status'] = "ok";
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privReadCentralFileHeader()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privReadCentralFileHeader(&$p_header)
{
$v_result = 1;
// ----- Read the 4 bytes signature
$v_binary_data = @fread($this->zip_fd, 4);
$v_data = unpack('Vid', $v_binary_data);
// ----- Check signature
if ($v_data['id'] != 0x02014b50) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
// ----- Return
return PclZip::errorCode();
}
// ----- Read the first 42 bytes of the header
$v_binary_data = fread($this->zip_fd, 42);
// ----- Look for invalid block size
if (strlen($v_binary_data) != 42) {
$p_header['filename'] = "";
$p_header['status'] = "invalid_header";
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : " . strlen($v_binary_data));
// ----- Return
return PclZip::errorCode();
}
// ----- Extract the values
$p_header = unpack(
'vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset',
$v_binary_data
);
// ----- Get filename
if ($p_header['filename_len'] != 0) {
$p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
} else {
$p_header['filename'] = '';
}
// ----- Get extra
if ($p_header['extra_len'] != 0) {
$p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
} else {
$p_header['extra'] = '';
}
// ----- Get comment
if ($p_header['comment_len'] != 0) {
$p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
} else {
$p_header['comment'] = '';
}
// ----- Extract properties
// ----- Recuperate date in UNIX format
//if ($p_header['mdate'] && $p_header['mtime'])
// TBC : bug : this was ignoring time with 0/0/0
if (1) {
// ----- Extract time
$v_hour = ($p_header['mtime'] & 0xF800) >> 11;
$v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
$v_seconde = ($p_header['mtime'] & 0x001F) * 2;
// ----- Extract date
$v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
$v_month = ($p_header['mdate'] & 0x01E0) >> 5;
$v_day = $p_header['mdate'] & 0x001F;
// ----- Get UNIX date format
$p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
} else {
$p_header['mtime'] = time();
}
// ----- Set the stored filename
$p_header['stored_filename'] = $p_header['filename'];
// ----- Set default status to ok
$p_header['status'] = 'ok';
// ----- Look if it is a directory
if (substr($p_header['filename'], -1) == '/') {
//$p_header['external'] = 0x41FF0010;
$p_header['external'] = 0x00000010;
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privCheckFileHeaders()
// Description :
// Parameters :
// Return Values :
// 1 on success,
// 0 on error;
// --------------------------------------------------------------------------------
function privCheckFileHeaders(&$p_local_header, &$p_central_header)
{
$v_result = 1;
// ----- Check the static values
// TBC
if ($p_local_header['filename'] != $p_central_header['filename']) {
}
if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
}
if ($p_local_header['flag'] != $p_central_header['flag']) {
}
if ($p_local_header['compression'] != $p_central_header['compression']) {
}
if ($p_local_header['mtime'] != $p_central_header['mtime']) {
}
if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
}
// ----- Look for flag bit 3
if (($p_local_header['flag'] & 8) == 8) {
$p_local_header['size'] = $p_central_header['size'];
$p_local_header['compressed_size'] = $p_central_header['compressed_size'];
$p_local_header['crc'] = $p_central_header['crc'];
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privReadEndCentralDir()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privReadEndCentralDir(&$p_central_dir)
{
$v_result = 1;
// ----- Go to the end of the zip file
$v_size = filesize($this->zipname);
@fseek($this->zip_fd, $v_size);
if (@ftell($this->zip_fd) != $v_size) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \'' . $this->zipname . '\''
);
// ----- Return
return PclZip::errorCode();
}
// ----- First try : look if this is an archive with no commentaries (most of the time)
// in this case the end of central dir is at 22 bytes of the file end
$v_found = 0;
if ($v_size > 26) {
@fseek($this->zip_fd, $v_size - 22);
if (($v_pos = @ftell($this->zip_fd)) != ($v_size - 22)) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\''
);
// ----- Return
return PclZip::errorCode();
}
// ----- Read for bytes
$v_binary_data = @fread($this->zip_fd, 4);
$v_data = @unpack('Vid', $v_binary_data);
// ----- Check signature
if ($v_data['id'] == 0x06054b50) {
$v_found = 1;
}
$v_pos = ftell($this->zip_fd);
}
// ----- Go back to the maximum possible size of the Central Dir End Record
if (!$v_found) {
$v_maximum_size = 65557; // 0xFFFF + 22;
if ($v_maximum_size > $v_size) {
$v_maximum_size = $v_size;
}
@fseek($this->zip_fd, $v_size - $v_maximum_size);
if (@ftell($this->zip_fd) != ($v_size - $v_maximum_size)) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \'' . $this->zipname . '\''
);
// ----- Return
return PclZip::errorCode();
}
// ----- Read byte per byte in order to find the signature
$v_pos = ftell($this->zip_fd);
$v_bytes = 0x00000000;
while ($v_pos < $v_size) {
// ----- Read a byte
$v_byte = @fread($this->zip_fd, 1);
// ----- Add the byte
//$v_bytes = ($v_bytes << 8) | Ord($v_byte);
// Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
// Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
$v_bytes = (($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
// ----- Compare the bytes
if ($v_bytes == 0x504b0506) {
$v_pos++;
break;
}
$v_pos++;
}
// ----- Look if not found end of central dir
if ($v_pos == $v_size) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
// ----- Return
return PclZip::errorCode();
}
}
// ----- Read the first 18 bytes of the header
$v_binary_data = fread($this->zip_fd, 18);
// ----- Look for invalid block size
if (strlen($v_binary_data) != 18) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : " . strlen($v_binary_data)
);
// ----- Return
return PclZip::errorCode();
}
// ----- Extract the values
$v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
// ----- Check the global size
if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
// ----- Removed in release 2.2 see readme file
// The check of the file size is a little too strict.
// Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
// While decrypted, zip has training 0 bytes
if (0) {
// ----- Error log
PclZip::privErrorLog(
PCLZIP_ERR_BAD_FORMAT,
'The central dir is not at the end of the archive.'
. ' Some trailing bytes exists after the archive.'
);
// ----- Return
return PclZip::errorCode();
}
}
// ----- Get comment
if ($v_data['comment_size'] != 0) {
$p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
} else {
$p_central_dir['comment'] = '';
}
$p_central_dir['entries'] = $v_data['entries'];
$p_central_dir['disk_entries'] = $v_data['disk_entries'];
$p_central_dir['offset'] = $v_data['offset'];
$p_central_dir['size'] = $v_data['size'];
$p_central_dir['disk'] = $v_data['disk'];
$p_central_dir['disk_start'] = $v_data['disk_start'];
// TBC
//for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
//}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privDeleteByRule()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privDeleteByRule(&$p_result_list, &$p_options)
{
$v_result = 1;
$v_list_detail = array();
// ----- Open the zip file
if (($v_result = $this->privOpenFd('rb')) != 1) {
// ----- Return
return $v_result;
}
// ----- Read the central directory informations
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
$this->privCloseFd();
return $v_result;
}
// ----- Go to beginning of File
@rewind($this->zip_fd);
// ----- Scan all the files
// ----- Start at beginning of Central Dir
$v_pos_entry = $v_central_dir['offset'];
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_pos_entry)) {
// ----- Close the zip file
$this->privCloseFd();
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
// ----- Return
return PclZip::errorCode();
}
// ----- Read each entry
$v_header_list = array();
$j_start = 0;
for ($i = 0, $v_nb_extracted = 0; $i < $v_central_dir['entries']; $i++) {
// ----- Read the file header
$v_header_list[$v_nb_extracted] = array();
if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1) {
// ----- Close the zip file
$this->privCloseFd();
return $v_result;
}
// ----- Store the index
$v_header_list[$v_nb_extracted]['index'] = $i;
// ----- Look for the specific extract rules
$v_found = false;
// ----- Look for extract by name rule
if ((isset($p_options[PCLZIP_OPT_BY_NAME]))
&& ($p_options[PCLZIP_OPT_BY_NAME] != 0)
) {
// ----- Look if the filename is in the list
for ($j = 0; ($j < sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
// ----- Look for a directory
if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
// ----- Look if the directory is in the filename path
if ((strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen(
$p_options[PCLZIP_OPT_BY_NAME][$j]
))
&& (substr(
$v_header_list[$v_nb_extracted]['stored_filename'], 0,
strlen($p_options[PCLZIP_OPT_BY_NAME][$j])
) == $p_options[PCLZIP_OPT_BY_NAME][$j])
) {
$v_found = true;
} elseif ((($v_header_list[$v_nb_extracted]['external'] & 0x00000010) == 0x00000010)
/* Indicates a folder */
&& ($v_header_list[$v_nb_extracted]['stored_filename'] . '/'
== $p_options[PCLZIP_OPT_BY_NAME][$j])
) {
$v_found = true;
}
} // ----- Look for a filename
elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
$v_found = true;
}
}
} // ----- Look for extract by ereg rule
// ereg() is deprecated with PHP 5.3
/*
else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
&& ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
$v_found = true;
}
}
*/
// ----- Look for extract by preg rule
else {
if ((isset($p_options[PCLZIP_OPT_BY_PREG]))
&& ($p_options[PCLZIP_OPT_BY_PREG] != "")
) {
if (preg_match(
$p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename']
)
) {
$v_found = true;
}
} // ----- Look for extract by index rule
else {
if ((isset($p_options[PCLZIP_OPT_BY_INDEX]))
&& ($p_options[PCLZIP_OPT_BY_INDEX] != 0)
) {
// ----- Look if the index is in the list
for ($j = $j_start; ($j < sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
if (($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['start'])
&& ($i <= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])
) {
$v_found = true;
}
if ($i >= $p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
$j_start = $j + 1;
}
if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start'] > $i) {
break;
}
}
} else {
$v_found = true;
}
}
}
// ----- Look for deletion
if ($v_found) {
unset($v_header_list[$v_nb_extracted]);
} else {
$v_nb_extracted++;
}
}
// ----- Look if something need to be deleted
if ($v_nb_extracted > 0) {
// ----- Creates a temporay file
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
// ----- Creates a temporary zip archive
$v_temp_zip = new PclZip($v_zip_temp_name);
// ----- Open the temporary zip file in write mode
if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
$this->privCloseFd();
// ----- Return
return $v_result;
}
// ----- Look which file need to be kept
for ($i = 0; $i < sizeof($v_header_list); $i++) {
// ----- Calculate the position of the header
@rewind($this->zip_fd);
if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
// ----- Close the zip file
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
// ----- Return
return PclZip::errorCode();
}
// ----- Read the file header
$v_local_header = array();
if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
// ----- Close the zip file
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
// ----- Return
return $v_result;
}
// ----- Check that local file header is same as central file header
if ($this->privCheckFileHeaders(
$v_local_header,
$v_header_list[$i]
) != 1
) {
// TBC
}
unset($v_local_header);
// ----- Write the file header
if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
// ----- Close the zip file
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
// ----- Return
return $v_result;
}
// ----- Read/write the data block
if (($v_result = PclZipUtilCopyBlock(
$this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size']
)) != 1
) {
// ----- Close the zip file
$this->privCloseFd();
$v_temp_zip->privCloseFd();
@unlink($v_zip_temp_name);
// ----- Return
return $v_result;
}
}
// ----- Store the offset of the central dir
$v_offset = @ftell($v_temp_zip->zip_fd);
// ----- Re-Create the Central Dir files header
for ($i = 0; $i < sizeof($v_header_list); $i++) {
// ----- Create the file header
if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
$v_temp_zip->privCloseFd();
$this->privCloseFd();
@unlink($v_zip_temp_name);
// ----- Return
return $v_result;
}
// ----- Transform the header to a 'usable' info
$v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
}
// ----- Zip file comment
$v_comment = '';
if (isset($p_options[PCLZIP_OPT_COMMENT])) {
$v_comment = $p_options[PCLZIP_OPT_COMMENT];
}
// ----- Calculate the size of the central header
$v_size = @ftell($v_temp_zip->zip_fd) - $v_offset;
// ----- Create the central dir footer
if ((
$v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment))
!= 1
) {
// ----- Reset the file list
unset($v_header_list);
$v_temp_zip->privCloseFd();
$this->privCloseFd();
@unlink($v_zip_temp_name);
// ----- Return
return $v_result;
}
// ----- Close
$v_temp_zip->privCloseFd();
$this->privCloseFd();
// ----- Delete the zip file
// TBC : I should test the result ...
@unlink($this->zipname);
// ----- Rename the temporary file
// TBC : I should test the result ...
//@rename($v_zip_temp_name, $this->zipname);
PclZipUtilRename($v_zip_temp_name, $this->zipname);
// ----- Destroy the temporary archive
unset($v_temp_zip);
} // ----- Remove every files : reset the file
else {
if ($v_central_dir['entries'] != 0) {
$this->privCloseFd();
if (($v_result = $this->privOpenFd('wb')) != 1) {
return $v_result;
}
if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
return $v_result;
}
$this->privCloseFd();
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privDirCheck()
// Description :
// Check if a directory exists, if not it creates it and all the parents directory
// which may be useful.
// Parameters :
// $p_dir : Directory path to check.
// Return Values :
// 1 : OK
// -1 : Unable to create directory
// --------------------------------------------------------------------------------
function privDirCheck($p_dir, $p_is_dir = false)
{
$v_result = 1;
// ----- Remove the final '/'
if (($p_is_dir) && (substr($p_dir, -1) == '/')) {
$p_dir = substr($p_dir, 0, strlen($p_dir) - 1);
}
// ----- Check the directory availability
if ((is_dir($p_dir)) || ($p_dir == "")) {
return 1;
}
// ----- Extract parent directory
$p_parent_dir = dirname($p_dir);
// ----- Just a check
if ($p_parent_dir != $p_dir) {
// ----- Look for parent directory
if ($p_parent_dir != "") {
if (($v_result = $this->privDirCheck($p_parent_dir)) != 1) {
return $v_result;
}
}
}
// ----- Create the directory
if (!@mkdir($p_dir, 0777)) {
// ----- Error log
PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
// ----- Return
return PclZip::errorCode();
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privMerge()
// Description :
// If $p_archive_to_add does not exist, the function exit with a success result.
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privMerge(&$p_archive_to_add)
{
$v_result = 1;
// ----- Look if the archive_to_add exists
if (!is_file($p_archive_to_add->zipname)) {
// ----- Nothing to merge, so merge is a success
$v_result = 1;
// ----- Return
return $v_result;
}
// ----- Look if the archive exists
if (!is_file($this->zipname)) {
// ----- Do a duplicate
$v_result = $this->privDuplicate($p_archive_to_add->zipname);
// ----- Return
return $v_result;
}
// ----- Open the zip file
if (($v_result = $this->privOpenFd('rb')) != 1) {
// ----- Return
return $v_result;
}
// ----- Read the central directory informations
$v_central_dir = array();
if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) {
$this->privCloseFd();
return $v_result;
}
// ----- Go to beginning of File
@rewind($this->zip_fd);
// ----- Open the archive_to_add file
if (($v_result = $p_archive_to_add->privOpenFd('rb')) != 1) {
$this->privCloseFd();
// ----- Return
return $v_result;
}
// ----- Read the central directory informations
$v_central_dir_to_add = array();
if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1) {
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
return $v_result;
}
// ----- Go to beginning of File
@rewind($p_archive_to_add->zip_fd);
// ----- Creates a temporay file
$v_zip_temp_name = PCLZIP_TEMPORARY_DIR . uniqid('pclzip-') . '.tmp';
// ----- Open the temporary file in write mode
if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0) {
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL,
'Unable to open temporary file \'' . $v_zip_temp_name . '\' in binary write mode'
);
// ----- Return
return PclZip::errorCode();
}
// ----- Copy the files from the archive to the temporary file
// TBC : Here I should better append the file and go back to erase the central dir
$v_size = $v_central_dir['offset'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($this->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Copy the files from the archive_to_add into the temporary file
$v_size = $v_central_dir_to_add['offset'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Store the offset of the central dir
$v_offset = @ftell($v_zip_temp_fd);
// ----- Copy the block of file headers from the old archive
$v_size = $v_central_dir['size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($this->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Copy the block of file headers from the archive_to_add
$v_size = $v_central_dir_to_add['size'];
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
@fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Merge the file comments
$v_comment = $v_central_dir['comment'] . ' ' . $v_central_dir_to_add['comment'];
// ----- Calculate the size of the (new) central header
$v_size = @ftell($v_zip_temp_fd) - $v_offset;
// ----- Swap the file descriptor
// Here is a trick : I swap the temporary fd with the zip fd, in order to use
// the following methods on the temporary fil and not the real archive fd
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
// ----- Create the central dir footer
if (($v_result = $this->privWriteCentralHeader(
$v_central_dir['entries'] + $v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment
)) != 1
) {
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
@fclose($v_zip_temp_fd);
$this->zip_fd = null;
// ----- Reset the file list
unset($v_header_list);
// ----- Return
return $v_result;
}
// ----- Swap back the file descriptor
$v_swap = $this->zip_fd;
$this->zip_fd = $v_zip_temp_fd;
$v_zip_temp_fd = $v_swap;
// ----- Close
$this->privCloseFd();
$p_archive_to_add->privCloseFd();
// ----- Close the temporary file
@fclose($v_zip_temp_fd);
// ----- Delete the zip file
// TBC : I should test the result ...
@unlink($this->zipname);
// ----- Rename the temporary file
// TBC : I should test the result ...
//@rename($v_zip_temp_name, $this->zipname);
PclZipUtilRename($v_zip_temp_name, $this->zipname);
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privDuplicate()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privDuplicate($p_archive_filename)
{
$v_result = 1;
// ----- Look if the $p_archive_filename exists
if (!is_file($p_archive_filename)) {
// ----- Nothing to duplicate, so duplicate is a success.
$v_result = 1;
// ----- Return
return $v_result;
}
// ----- Open the zip file
if (($v_result = $this->privOpenFd('wb')) != 1) {
// ----- Return
return $v_result;
}
// ----- Open the temporary file in write mode
if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0) {
$this->privCloseFd();
PclZip::privErrorLog(
PCLZIP_ERR_READ_OPEN_FAIL,
'Unable to open archive file \'' . $p_archive_filename . '\' in binary write mode'
);
// ----- Return
return PclZip::errorCode();
}
// ----- Copy the files from the archive to the temporary file
// TBC : Here I should better append the file and go back to erase the central dir
$v_size = filesize($p_archive_filename);
while ($v_size != 0) {
$v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = fread($v_zip_temp_fd, $v_read_size);
@fwrite($this->zip_fd, $v_buffer, $v_read_size);
$v_size -= $v_read_size;
}
// ----- Close
$this->privCloseFd();
// ----- Close the temporary file
@fclose($v_zip_temp_fd);
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privErrorLog()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function privErrorLog($p_error_code = 0, $p_error_string = '')
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
PclError($p_error_code, $p_error_string);
} else {
$this->error_code = $p_error_code;
$this->error_string = $p_error_string;
}
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privErrorReset()
// Description :
// Parameters :
// --------------------------------------------------------------------------------
function privErrorReset()
{
if (PCLZIP_ERROR_EXTERNAL == 1) {
PclErrorReset();
} else {
$this->error_code = 0;
$this->error_string = '';
}
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privDisableMagicQuotes()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privDisableMagicQuotes()
{
$v_result = 1;
// ----- Look if function exists
if ((!function_exists("get_magic_quotes_runtime"))
|| (!function_exists("set_magic_quotes_runtime"))
) {
return $v_result;
}
// ----- Look if already done
if ($this->magic_quotes_status != -1) {
return $v_result;
}
// ----- Get and memorize the magic_quote value
$this->magic_quotes_status = @get_magic_quotes_runtime();
// ----- Disable magic_quotes
if ($this->magic_quotes_status == 1) {
@set_magic_quotes_runtime(0);
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : privSwapBackMagicQuotes()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function privSwapBackMagicQuotes()
{
$v_result = 1;
// ----- Look if function exists
if ((!function_exists("get_magic_quotes_runtime"))
|| (!function_exists("set_magic_quotes_runtime"))
) {
return $v_result;
}
// ----- Look if something to do
if ($this->magic_quotes_status != -1) {
return $v_result;
}
// ----- Swap back magic_quotes
if ($this->magic_quotes_status == 1) {
@set_magic_quotes_runtime($this->magic_quotes_status);
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
}
// End of class
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : PclZipUtilPathReduction()
// Description :
// Parameters :
// Return Values :
// --------------------------------------------------------------------------------
function PclZipUtilPathReduction($p_dir)
{
$v_result = "";
// ----- Look for not empty path
if ($p_dir != "") {
// ----- Explode path by directory names
$v_list = explode("/", $p_dir);
// ----- Study directories from last to first
$v_skip = 0;
for ($i = sizeof($v_list) - 1; $i >= 0; $i--) {
// ----- Look for current path
if ($v_list[$i] == ".") {
// ----- Ignore this directory
// Should be the first $i=0, but no check is done
} else {
if ($v_list[$i] == "..") {
$v_skip++;
} else {
if ($v_list[$i] == "") {
// ----- First '/' i.e. root slash
if ($i == 0) {
$v_result = "/" . $v_result;
if ($v_skip > 0) {
// ----- It is an invalid path, so the path is not modified
// TBC
$v_result = $p_dir;
$v_skip = 0;
}
} // ----- Last '/' i.e. indicates a directory
else {
if ($i == (sizeof($v_list) - 1)) {
$v_result = $v_list[$i];
} // ----- Double '/' inside the path
else {
// ----- Ignore only the double '//' in path,
// but not the first and last '/'
}
}
} else {
// ----- Look for item to skip
if ($v_skip > 0) {
$v_skip--;
} else {
$v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? "/" . $v_result : "");
}
}
}
}
}
// ----- Look for skip
if ($v_skip > 0) {
while ($v_skip > 0) {
$v_result = '../' . $v_result;
$v_skip--;
}
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : PclZipUtilPathInclusion()
// Description :
// This function indicates if the path $p_path is under the $p_dir tree. Or,
// said in an other way, if the file or sub-dir $p_path is inside the dir
// $p_dir.
// The function indicates also if the path is exactly the same as the dir.
// This function supports path with duplicated '/' like '//', but does not
// support '.' or '..' statements.
// Parameters :
// Return Values :
// 0 if $p_path is not inside directory $p_dir
// 1 if $p_path is inside directory $p_dir
// 2 if $p_path is exactly the same as $p_dir
// --------------------------------------------------------------------------------
function PclZipUtilPathInclusion($p_dir, $p_path)
{
$v_result = 1;
// ----- Look for path beginning by ./
if (($p_dir == '.')
|| ((strlen($p_dir) >= 2) && (substr($p_dir, 0, 2) == './'))
) {
$p_dir = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_dir, 1);
}
if (($p_path == '.')
|| ((strlen($p_path) >= 2) && (substr($p_path, 0, 2) == './'))
) {
$p_path = PclZipUtilTranslateWinPath(getcwd(), false) . '/' . substr($p_path, 1);
}
// ----- Explode dir and path by directory separator
$v_list_dir = explode("/", $p_dir);
$v_list_dir_size = sizeof($v_list_dir);
$v_list_path = explode("/", $p_path);
$v_list_path_size = sizeof($v_list_path);
// ----- Study directories paths
$i = 0;
$j = 0;
while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
// ----- Look for empty dir (path reduction)
if ($v_list_dir[$i] == '') {
$i++;
continue;
}
if ($v_list_path[$j] == '') {
$j++;
continue;
}
// ----- Compare the items
if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ($v_list_path[$j] != '')) {
$v_result = 0;
}
// ----- Next items
$i++;
$j++;
}
// ----- Look if everything seems to be the same
if ($v_result) {
// ----- Skip all the empty items
while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) {
$j++;
}
while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) {
$i++;
}
if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
// ----- There are exactly the same
$v_result = 2;
} else {
if ($i < $v_list_dir_size) {
// ----- The path is shorter than the dir
$v_result = 0;
}
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : PclZipUtilCopyBlock()
// Description :
// Parameters :
// $p_mode : read/write compression mode
// 0 : src & dest normal
// 1 : src gzip, dest normal
// 2 : src normal, dest gzip
// 3 : src & dest gzip
// Return Values :
// --------------------------------------------------------------------------------
function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode = 0)
{
$v_result = 1;
if ($p_mode == 0) {
while ($p_size != 0) {
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($p_src, $v_read_size);
@fwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
} else {
if ($p_mode == 1) {
while ($p_size != 0) {
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @gzread($p_src, $v_read_size);
@fwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
} else {
if ($p_mode == 2) {
while ($p_size != 0) {
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @fread($p_src, $v_read_size);
@gzwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
} else {
if ($p_mode == 3) {
while ($p_size != 0) {
$v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
$v_buffer = @gzread($p_src, $v_read_size);
@gzwrite($p_dest, $v_buffer, $v_read_size);
$p_size -= $v_read_size;
}
}
}
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : PclZipUtilRename()
// Description :
// This function tries to do a simple rename() function. If it fails, it
// tries to copy the $p_src file in a new $p_dest file and then unlink the
// first one.
// Parameters :
// $p_src : Old filename
// $p_dest : New filename
// Return Values :
// 1 on success, 0 on failure.
// --------------------------------------------------------------------------------
function PclZipUtilRename($p_src, $p_dest)
{
$v_result = 1;
// ----- Try to rename the files
if (!@rename($p_src, $p_dest)) {
// ----- Try to copy & unlink the src
if (!@copy($p_src, $p_dest)) {
$v_result = 0;
} else {
if (!@unlink($p_src)) {
$v_result = 0;
}
}
}
// ----- Return
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : PclZipUtilOptionText()
// Description :
// Translate option value in text. Mainly for debug purpose.
// Parameters :
// $p_option : the option value.
// Return Values :
// The option text value.
// --------------------------------------------------------------------------------
function PclZipUtilOptionText($p_option)
{
$v_list = get_defined_constants();
for (reset($v_list); $v_key = key($v_list); next($v_list)) {
$v_prefix = substr($v_key, 0, 10);
if ((($v_prefix == 'PCLZIP_OPT')
|| ($v_prefix == 'PCLZIP_CB_')
|| ($v_prefix == 'PCLZIP_ATT'))
&& ($v_list[$v_key] == $p_option)
) {
return $v_key;
}
}
$v_result = 'Unknown';
return $v_result;
}
// --------------------------------------------------------------------------------
// --------------------------------------------------------------------------------
// Function : PclZipUtilTranslateWinPath()
// Description :
// Translate windows path by replacing '\' by '/' and optionally removing
// drive letter.
// Parameters :
// $p_path : path to translate.
// $p_remove_disk_letter : true | false
// Return Values :
// The path translated.
// --------------------------------------------------------------------------------
function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter = true)
{
if (stristr(php_uname(), 'windows')) {
// ----- Look for potential disk letter
if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
$p_path = substr($p_path, $v_position + 1);
}
// ----- Change potential windows directory separator
if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) {
$p_path = strtr($p_path, '\\', '/');
}
}
return $p_path;
}
// --------------------------------------------------------------------------------
?>
================================================
FILE: extensions/exconf/resources/Examples.rdf
================================================
]>
OWL for the Miniworld of the Extension Repository Schemea Extension pluggable script that interacts with Ontowiki to provide a certain, usually very specific, function "on demand".Every developer must have a password together with nickname for the authentificaitontime of last metadata change of the Extensionmark extensions that can not coexist with this one. maybe because they are interchangeable but contradictionary.mark extensions that are needed by this extension to work properly.qiufengFengQiuaccount_1qiufengAricQiuaccount_1informatikChristianMaieraccount_3This is a very very very very very svery very very very very very very very very short desciption for test_plugin_12009-03-15T13:00:00.000test_plugin_1This is a very svery very very very very svery very very very very very very short description for test_plugin_22009-03-15T12:51:36.000test_plugin_2This is a very very svery very very very very svery very very very very very very short description for test_plugin_32009-03-15T12:51:36.000test_plugin_3A plugin that renders values of certain properties as audio.2009-05-02T13:00:00.000audiolinkA plugin that renders values of certain properties as video.2009-05-02T13:00:00.000videolinkhttp://stinfwww.informatik.uni-leipzig.de/~bss03kpx/testplugin1.zip1.0TestPluginOntowikiExtensionhttp://stinfwww.informatik.uni-leipzig.de/~bss03kpx/testplugin2.zip1.0TestPluginOntowikiExtensionhttp://stinfwww.informatik.uni-leipzig.de/~bss03kpx/testplugin3.zip1.0TestPluginOntowikiExtensionhttp://stinfwww.informatik.uni-leipzig.de/~bss03kpx/audiolink.zip1.0AudioPluginOntowikiExtensionLinkChristianMaierhttp://stinfwww.informatik.uni-leipzig.de/~bss03kpx/videolink.zip1.0VideoPluginOntowikiExtensionLinkChristianMaier
================================================
FILE: extensions/exconf/resources/PluginRepository.rdf
================================================
]>
OWL for the Miniworld of the Extension Repository Schemea Extension pluggable script that interacts with Ontowiki to provide a certain, usually very specific, function "on demand".Every developer must have a password together with nickname for the authentificaitontime of last metadata change of the Extensionmark extensions that can not coexist with this one. maybe because they are interchangeable but contradictionary.mark extensions that are needed by this extension to work properly.
================================================
FILE: extensions/exconf/resources/exconf.css
================================================
/**
* Defines special elements for the extension configurator
* @author haschek
* @since 03.02.2011, 19:29:44
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
#show_extension input, legend
{
position:absolute;
left:-5000em;
}
#show_extension fieldset
{
margin-top: 0.5em;
list-style: none;
margin-left: 0;
padding: 0 0.5em;
overflow:hidden;
border-bottom:solid 1px #666;
position:relative;
}
#show_extension label
{
float: left;
white-space: nowrap;
display: block;
position: relative;
top: 0.1em;
border-color: #999;
border-bottom-color: #666;
border-width: 1px 1px 0.1em 1px;
border-style: solid;
border-left-style: none;
padding: 0.5em 1em;
text-decoration: none;
color: #333;
background: url(./../../themes/silverblue/images/layout-tab-gradient.png) repeat-x bottom center #dfdfdf;
cursor: pointer;
}
#show_extension fieldset legend + input + label
{
border-left-style: solid;
}
#show_extension label.active
{
border-color: #666;
border-bottom: none;
padding-bottom: 0.6em;
background: url(./../../themes/silverblue/images/layout-tabactive-gradient.png) repeat-x top center #fff;
z-index: 1;
color: #333;
font-weight: bold;
}
#show_extension label.toggler_view
{
float:right;
padding:0;
margin:0;
border:none;
width:45px;
height:25px;
position:absolute;
right:1em; top:50%; margin-top:-13px;
background:url(viewtoggler.png) no-repeat left top transparent;
text-indent: -5000em;
cursor:pointer;
}
#show_extension label.toggler_view:hover,
.view_compact #show_extension label.toggler_view
{
background-position:left bottom;
}
.view_compact #show_extension label.toggler_view:hover
{
background-position:left top;
}
#extensions li
{
padding:0.5em 0.5em 0.5em 1.5em;
position:relative;
}
#extensions li > .icon
{
position:absolute;
left:0;
top:0.5em;
}
#extensions h3
{
margin:0;
display:inline-block;
}
#extensions h3 em
{
font-size: 0.8em;
}
li.compact div.extension > *
{
display:none;
}
li.compact div.extension h3
{
display:inline-block;
font-size:1em;
font-weight:bold;
padding-right: 0.25em;
}
li.compact div.extension h3 em
{
display:none;
}
li.compact div.extension .togglebutton
{
display:inline-block;
}
li.compact .togglebutton .slider { display:none; }
================================================
FILE: extensions/exconf/resources/exconf.js
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
$(function()
{
function postToggle(button)
{
var name = $(button).parent().attr("id").replace('extension-', '');
var enabled = $(button).prop("selected");
$.post(urlBase + "exconf/conf/?name="+name+"&enabled="+enabled,function(data){if(data==""){$("#numEnabled").html(parseInt($("#numEnabled").html())+( enabled == "true" ? 1 : -1));$("#numDisabled").html(parseInt($("#numDisabled").html())+( enabled == "true" ? -1 : 1));}});
}
$(".togglebutton").togglebutton(
{"onEnable":
postToggle,
"onDisable":
postToggle
}
);
$("#show_extension input#viewCompact").change(function()
{
if ($(this).is(":checked"))
{
$("div.view_extended").addClass("view_compact").removeClass("view_extended");
$("#extensions li").addClass("compact");
$("#extensions li a.toggle").addClass('icon-arrow-next').removeClass('icon-arrow-down');
}
else
{
$("div.view_compact").addClass("view_extended").removeClass("view_compact");
$("#extensions li").removeClass("compact");
$("#extensions li a.toggle").addClass('icon-arrow-down').removeClass('icon-arrow-next');
}
});
$("#extensions a.toggle").click(function()
{
if ($(this).is('.icon-arrow-down'))
{
$(this).parent('li').addClass('compact');
$(this).addClass('icon-arrow-next').removeClass('icon-arrow-down');
}
else
{
$(this).parent('li').removeClass('compact');
$(this).addClass('icon-arrow-down').removeClass('icon-arrow-next');
}
});
$("#show_extension input:radio").change(function()
{
$("#show_extension label").removeClass("active");
switch($("#show_extension input:checked").val()){
case "all" :
$("#show_extension label[for=showAll]").addClass("active");
$("#extensions li").each(function(){
$(this).show();
})
break;
case "enabled" :
$("#show_extension label[for=showEnabled]").addClass("active");
$("#extensions li").each(function(){if($(this).find(".togglebutton").prop("selected") == "true"){
$(this).show();
} else {
$(this).hide();
}})
break;
case "disabled" :
$("#show_extension label[for=showDisabled]").addClass("active");
$("#extensions li").each(function(){if($(this).find(".togglebutton").prop("selected") == "true"){
$(this).hide();
} else {
$(this).show();
}})
break;
}
// re-populate the outline
extensionOutline();
//fix odd even style
var even = true;
$("#extensions li:visible").each(function(){
if(even){
$(this).addClass("even").removeClass("odd");
} else {
$(this).addClass("odd").removeClass("even");
}
even = !even;
})
}
);
});
================================================
FILE: extensions/exconf/resources/jquery.togglebutton.js
================================================
/*
turn a div or checkbox into a sliding toggle switch (like the apple slide to unlock)
*/
/*# AVOID COLLISIONS #*/
if(window.jQuery) (function($){
/*# AVOID COLLISIONS #*/
// plugin initialization
$.fn.togglebutton = function(options){
// Initialize options for this call
var options = $.extend(
{}/* new object */,
$.fn.togglebutton.options/* default options */,
options || {} /* just-in-time options */
);
function enable(button, withCallback){
var realChange = false;
if(button.prop("selected") != "true"){
realChange = true;
}
button.prop("selected", "true");
button.css("background-color", "#a0e876");
var slider = button.find("> .slider").eq(0);
slider.animate({left:0}, parseInt(100,10));
if(realChange && withCallback && options.onEnable && typeof options.onEnable == "function"){
options.onEnable(button);
}
}
function disable(button, withCallback){
var realChange = false;
if(button.prop("selected") != "false"){
realChange = true;
}
button.prop("selected", "false");
button.css("background-color", "#e95d46");
var slider = button.find("> .slider").eq(0);
slider.animate({left:button.width() - slider.width()}, parseInt(100,10));
if(realChange && withCallback && options.onDisable && typeof options.onDisable == "function"){
options.onDisable(button);
}
}
// loop through each matched element
this.each(function(){
var container = $(this);
if(!container.is("div")){
var newNode = $("");
container.replaceWith(newNode); //returns the old node
// initialize property based on attribute
if(container.is(":checked") || container.attr("selected") == "selected"){
newNode.prop("selected", "true");
}
container = newNode;
}
container.addClass('togglebutton');
var slider = $("").addClass("slider");
container.append(slider);
if(!container.hasClass("frozen")){
slider.draggable({
axis:"x",
containment:"parent",
snapMode:"inner",
snapTolerance:10,
scroll: false
});
}
var ref = slider.position().left;
// initialize property based on attribute
if(options.enabled || container.is(":checked") || container.attr("selected") == "selected"){
container.prop("selected","true");
enable(container, false);
} else {
container.prop("selected","false");
disable(container, false);
}
container.droppable({
accept: ".slider",
drop: function(){
if(container.hasClass("frozen")){
return;
}
var l = slider.position().left - ref;
var r = container.width() - l - slider.width();
if(l < r){
enable(container, true);
} else {
disable(container, true);
}
}
});
container.click(function(){
if(container.hasClass("frozen")){
return;
}
if(container.prop('selected')=='true'){
disable(container, true);
} else {
enable(container, true);
}
});
}); // each element
return this; // don't break the chain...
};
/*--------------------------------------------------------*/
/*
### Core functionality and API ###
*/
$.extend($.fn.togglebutton, {
selected: function(){
return $(this).prop("selected") == "true";
}
});
/*--------------------------------------------------------*/
/*
### Default Settings ###
eg.: You can override default control like this:
$.fn.rating.options.cancel = 'Clear';
*/
$.fn.togglebutton.options = { };
/*--------------------------------------------------------*/
/*
### Default implementation ###
The plugin will attach itself to divs with class togglebutton when the page loads
*/
$(function(){
});
/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/
================================================
FILE: extensions/exconf/resources/outline.js
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
$(document).ready(function() {
extensionOutline();
});
function extensionOutline() {
var target = $('div.outline').empty();
target = target.append('').children('ol');
var even = true;
$('div.extension:visible').each(function(){
var title = $(this).find('.name').text();
var id = $(this).attr('id');
if(even){
target.append('
+
headScript()->appendFile($ow->extensionManager->getComponentUrl('exconf')."resources/jquery.togglebutton.js");
$this->headLink()->appendStylesheet($ow->extensionManager->getComponentUrl('exconf')."resources/togglebutton.css");
$this->headScript()->appendScript('var exconfConfig = '. json_encode($this->config).';
$(document).ready(function(){
function postToggle(button)
{
//no posting here, will be submitted with the form
}
$(".togglebutton").togglebutton(
{"onEnable":
postToggle,
"onDisable":
postToggle
}
);
//handle the form myself
$("div.toolbar a.button.submit").unbind("click");
$("div.toolbar a.button.submit").click(function(){
var arr = form2array($("#topConfTable"));
$("#exConf input[name=config]").val($.toJSON(arr));
$("#exConf").submit();
//old get method cause problems with too long URIs
//window.location = urlBase+"exconf/conf?name='.$this->name.'&config="+encodeURIComponent($.toJSON(arr));
});
$(".addProperty").submit(function(){return false;});
$(".addProperty").live("click",function(){
var lastKey = $(this).parent().find(">table>tbody>tr:last>td:first>input").val();
var lastKeyInt = parseInt(lastKey);
if(!isNaN(lastKeyInt)){
var key = lastKeyInt+1;
} else {
var key = lastKey+"x";
}
$(this).prev().append("
+");
$(this).remove();
});
});
function form2array(node){
var arr = {};
node.find("> tbody > tr").each(function(){
var field = $(this);
var key = $(this).find(">td:first");
if($(key).find("input").is("input")){
var name = $(key).find("input").val();
} else {
var name = key.html();
}
var nameInt = parseInt(name);
if(!isNaN(nameInt)){
name = nameInt;
}
var value = $(this).find("> td").eq(1).find("> *:first");
if($(value).is("table")){
value = form2array(value);
} else if( $(value).text() == "[empty]+"){
value = {};
} else if( $(value).is("input[type=checkbox]")){
value = $(value).is(":checked");
} else if( $(value).is("div.togglebutton")){
value = ($(value).prop("selected") == "true");
} else if( $(value).is("input.text")){
value = $(value).val();
}
arr[name] = value;
});
return arr;
}');
?>
you can change values of your local config here. you can also change the structure of the config, but only do it when you really know what you are doing.
missing doap:file-release link on newest doap:Version
_('No extensions found.') ?>
================================================
FILE: extensions/filter/CustomfilterModule.php
================================================
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class CustomfilterModule extends OntoWiki_Module
{
protected $_instances = null;
public function init()
{
}
public function getTitle()
{
return 'Custom Filter';
}
public function getContents()
{
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
$this->_instances = $listHelper->getLastList();
if (!($this->_instances instanceof OntoWiki_Model_Instances)) {
return "Error: List not found";
}
$this->store = $this->_owApp->erfurt->getStore();
$this->model = $this->_owApp->selectedModel;
$this->titleHelper = new OntoWiki_Model_TitleHelper($this->_owApp->selectedModel);
$this->view->headLink()->appendStylesheet($this->view->moduleUrl . 'resources/filter.css');
$this->view->headScript()->appendFile($this->view->moduleUrl . 'resources/jquery.dump.js');
$this->view->headScript()->appendFile($this->view->moduleUrl . 'resources/filter.js');
$this->view->definedfilters = $this->_privateConfig->customfilter->toArray();
$content = $this->render('filter/complexfilter');
return $content;
}
}
================================================
FILE: extensions/filter/FilterController.php
================================================
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class FilterController extends OntoWiki_Controller_Component
{
public function getpossiblevaluesAction()
{
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
$listName = $this->_request->getParam('list');
if ($listHelper->listExists($listName)) {
$list = $listHelper->getList($listName);
//TODO the store is not serialized anymore. it is missing by default. Controllers have to set it
//how to determine here?
//use the default store here - but also Sparql-Adapters are possible
$list->setStore($this->_erfurt->getStore());
} else {
$this->view->values = array();
return;
}
$predicate = $this->_request->getParam('predicate', '');
$inverse = $this->_request->getParam('inverse', '');
$this->view->values = $list->getPossibleValues($predicate, true, $inverse == "true");
require_once 'OntoWiki/Model/TitleHelper.php';
$titleHelper = new OntoWiki_Model_TitleHelper($this->_owApp->selectedModel);
foreach ($this->view->values as $value) {
if ($value['type'] == 'uri') {
$titleHelper->addResource($value['value']);
}
}
foreach ($this->view->values as $key => $value) {
if ($value['type'] == 'uri') {
$this->view->values[$key]['title'] = $titleHelper->getTitle($value['value']);
} else {
$this->view->values[$key]['title'] = $value['value'];
}
}
}
}
================================================
FILE: extensions/filter/FilterModule.php
================================================
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class FilterModule extends OntoWiki_Module
{
protected $_instances = null;
public function init()
{
}
public function getTitle()
{
return 'Filter';
}
public function getContents()
{
$listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List');
$this->_instances = $listHelper->getLastList();
if (!($this->_instances instanceof OntoWiki_Model_Instances)) {
return "Error: List not found";
}
$this->store = $this->_owApp->erfurt->getStore();
$this->model = $this->_owApp->selectedModel;
$this->titleHelper = new OntoWiki_Model_TitleHelper($this->_owApp->selectedModel);
$this->view->headLink()->appendStylesheet($this->view->moduleUrl . 'resources/filter.css');
//$this->view->headScript()->appendFile($this->view->moduleUrl . 'resources/jquery.dump.js');
$this->view->properties = $this->_instances->getAllProperties(false);
$this->view->inverseProperties = $this->_instances->getAllProperties(true);
$this->view->actionUrl = $this->_config->staticUrlBase . 'index.php/list/';
$this->view->s = $this->_request->s;
$this->view->filter = $this->_instances->getFilter();
if (is_array($this->view->filter)) {
foreach ($this->view->filter as $key => $filter) {
switch ($filter['mode']) {
case 'box':
if ($filter['property']) {
$this->view->filter[$key]['property'] = trim($filter['property']);
$this->titleHelper->addResource($filter['property']);
}
if ($filter['valuetype'] == 'uri' && !empty($filter['value1'])) {
$this->titleHelper->addResource($filter['value1']);
}
if ($filter['valuetype'] == 'uri' && !empty($filter['value2'])) {
$this->titleHelper->addResource($filter['value2']);
}
break;
case 'rdfsclass':
$this->titleHelper->addResource($filter['rdfsclass']);
break;
}
}
}
$this->view->titleHelper = $this->titleHelper;
$this->view->headScript()->appendFile($this->view->moduleUrl . 'resources/filter.js');
$content = $this->render('filter/filter');
return $content;
}
public function getMenu()
{
$edit = new OntoWiki_Menu();
$edit->setEntry('Add', 'javascript:showAddFilterBox()')
->setEntry('Remove all', 'javascript:removeAllFilters()');
$help = new OntoWiki_Menu();
$help->setEntry('Toggle help', 'javascript:toggleHelp()');
$main = new OntoWiki_Menu();
$main->setEntry('Edit', $edit);
$main->setEntry('Help', $help);
return $main;
}
}
================================================
FILE: extensions/filter/default.ini
================================================
;;
; Basic component configuration
;;
templates = "templates"
enabled = true
name = "Filter Resource Lists"
description = "provides a GUI to apply filters on a list of resources."
author = "AKSW"
authorUrl = "http://aksw.org"
modules.filter.priority = 30
modules.filter.contexts.0 = "main.window.list"
;modules.customfilter.enabled = false
;modules.customfilter.priority = 40
;modules.customfilter.contexts.0 = "main.window.list"
;;
; Component's private configuration
; Anything set below will be available within the component ($this->_privateConfig->key)
;;
[private]
customfilter.prop1.uri = "http://example.com/aProp1/"
customfilter.prop1.label = "prop1"
customfilter.prop1.value1.uri = "http://example.com/aVal11/"
customfilter.prop1.value1.label = "val11"
customfilter.prop1.value2.uri = "http://example.com/aVal12/"
customfilter.prop1.value2.label = "val12"
customfilter.prop2.uri = "http://example.com/aProp2/"
customfilter.prop2.label = "prop2"
customfilter.prop2.value1.uri = "http://example.com/aVal21/"
customfilter.prop2.value1.label = "val21"
customfilter.prop2.value2.uri = "http://example.com/aVal22/"
customfilter.prop2.value2.label = "val22"
================================================
FILE: extensions/filter/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :filter .
:filter a doap:Project ;
doap:name "filter" ;
owconfig:privateNamespace ;
owconfig:templates "templates" ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Filter Resource Lists" ;
doap:description "provides a GUI to apply filters on a list of resources." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:hasModule :Filter .
:Filter a owconfig:Module ;
rdfs:label "Filter" ;
owconfig:priority "30" ;
owconfig:context "main.window.list" .
:filter owconfig:config [
a owconfig:Config;
owconfig:id "customfilter";
owconfig:config [
a owconfig:Config;
owconfig:id "prop1";
:uri ;
:label "prop1" ;
owconfig:config [
a owconfig:Config;
owconfig:id "value1";
:uri ;
:label "val11"
];
owconfig:config [
a owconfig:Config;
owconfig:id "value2";
:uri ;
:label "val12"
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "prop2";
:uri ;
:label "prop2" ;
owconfig:config [
a owconfig:Config;
owconfig:id "value1";
:uri ;
:label "val21"
];
owconfig:config [
a owconfig:Config;
owconfig:id "value2";
:uri ;
:label "val22"
]
]
] .
:filter doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/filter/resources/FilterAPI.js
================================================
/**
* @class
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
function FilterAPI(){
/*
* @var
*/
this.uri = reloadUrl;
/*
*@var array
*/
this.callbacks = new Array();
/**
* @var array
*/
this.filters = filtersFromSession;
/**
* @var int
*/
this.count = 0;
for(onefilter in filtersFromSession){
this.count++;
}
/**
*@method
*
*/
this.addCallback = function(callback){
if(typeof callback == 'function' || typeof callback == 'object')
this.callbacks.push(callback);
};
/**
*@method
*
*/
this.removeAllFiltersOfProperty = function(uri){
var data = { filter: [] }
for(afilterName in this.filters){
if(this.filters[afilterName].property == uri){
data.filter.push({
"mode" : "box",
"action" : "remove",
"id" : this.filters[afilterName].id
})
}
}
var dataserialized = $.toJSON(data);
var url = this.uri + "?instancesconfig=" + encodeURIComponent(dataserialized)+"&list="+listName;
//alert(dataserialized)
window.location = url;
};
/**
* add a filter
* @method
* @param id int,string
* @param property string an iri (predicate) which values should be filtered
* @param isInverse boolean if the property is inverse
* @param propertyLabel string a label for the property (will be displayed instead)
* @param filter string can be "contains" or "equals" . going to be enhanced
* @param value1 mixed the value applied to the filter
* @param value2 mixed the value applied to the filter. often optional (used for "between")
* @param valuetype string may be "uri" or "literal" or "typedliteral" or "langtaggedliteral"
* @param literaltype string if valuetype is "typedliteral" or "langtaggedliteral": you can put stuff like "de" or "xsd:int" here...
* @param callback function will be called on success
* @param hidden boolean will not show up in filterbox if true
* @param negate
* @param dontReload prevent page reloading
*/
this.add = function(id, property, isInverse, propertyLabel, filter, value1, value2, valuetype, literaltype, callback, hidden, negate, dontReload){
if(typeof callback != 'function' && typeof callback != 'object'){
callback = function(){};
}
if(id == null){
id = "filterbox"+this.count
}
var data =
{
filter:
[
{
"mode" : "box",
"action" : "add",
"id" : id,
"property" : property,
"isInverse" : typeof isInverse != 'undefined' ? isInverse : false,
"propertyLabel" : typeof propertyLabel != 'undefined' ? propertyLabel : null,
"filter" : filter,
"value1": value1,
"value2": typeof value2 != 'undefined' ? value2 : null,
"valuetype": typeof valuetype != 'undefined' ? valuetype : null,
"literaltype" : typeof literaltype != 'undefined' ? literaltype : null,
"hidden" : typeof hidden != 'undefined' ? hidden : false,
"negate" : typeof negate != 'undefined' ? negate : false
}
]
};
var dataserialized = $.toJSON(data);
var url = this.uri + "?instancesconfig=" + encodeURIComponent(dataserialized)+"&list="+listName;
this.count++;
if(dontReload == true){
$.ajax(
{
"url": url,
"type" : "POST"
}
);
} else {
window.location = url;
}
};
this.reloadInstances = function(){
//$('.content .innercontent').load(document.URL);
//window.location = this.uri;
};
this.filterExists = function(id){
return (typeof this.filters[id] != 'undefined');
}
this.getFilterById = function(id){
return this.filters[id];
}
this.remove = function(id, callback){
if(typeof callback != 'function' && typeof callback != 'object')
callback = function(){};
var data = {
filter: [
{
"action" : "remove",
"id" : id
}
]
};
var dataserialized = $.toJSON(data);
this.count--;
window.location = this.uri + "?instancesconfig=" + encodeURIComponent(dataserialized);
};
this.removeAll = function(){
this.count = 0;
window.location = this.uri+"?init"
};
}
var filter = new FilterAPI();
================================================
FILE: extensions/filter/resources/filter.css
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
#cancelrestrictionbutton {
color: red;
}
.gqbclassrestrictionvalueselector {
width: 60px;
}
#gqbclassrestrictionsnotexist {
font-style: italic;
color: grey;
}
.gqb-button-add {
background: url(images/icon-add-grey.png) 0 0 no-repeat center;
}
.gqb-button-add:hover {
background: url(images/icon-add.png) 0 0 no-repeat center;
}
span.gqb-button-delete {
background: url(../extensions/components/graphicalquerybuilder/resources/images/icon-delete-grey.png) no-repeat center;
}
span.gqb-button-delete:hover {
background: url(../extensions/components/graphicalquerybuilder/resources/images/icon-delete.png) no-repeat center;
}
span.gqb-button-edit {
background: url(images/icon-edit-grey.png) no-repeat center;
}
span.gqb-button-edit:hover {
background: url(images/icon-edit.png) no-repeat center;
}
================================================
FILE: extensions/filter/resources/filter.js
================================================
/*
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
var filterboxcounter = 0; // dont overwrite previous filters
function showAddFilterBox(){
// $("#addFilterWindowOverlay").show();
$("#addFilterWindowOverlay").modal({
overlay: 80,
overlayCss: {backgroundColor: '#000'},
overlayClose: true,
onOpen: function (dialog) {
dialog.overlay.fadeIn(effectTime, function () {
dialog.data.show();
dialog.container.fadeIn(effectTime);
})
},
onClose: function (dialog) {
dialog.container.fadeOut(effectTime, function() {
dialog.overlay.fadeOut(effectTime, function() {
$.modal.close();
});
});
}
});
}
function updatePossibleValues() {
if($("#property option:selected").length == 0) {return;}
$("#addwindow #possiblevalues").addClass("is-processing");
$("#property option:selected").each(function () {
var inverse = $(this).hasClass("InverseProperty") ? "true" : "false";
$("#possiblevalues").load(urlBase+"filter/getpossiblevalues?predicate="+escape($(this).attr("about"))+"&inverse="+inverse+"&list="+listName, {}, function(){
$("#addwindow #possiblevalues").removeClass("is-processing");
});
});
}
function removeAllFilters(){
// $("#addFilterWindowOverlay").hide();
$.modal.close();
filter.removeAll(function() {
});
}
function toggleHelp(){
$("#helptext").slideToggle();
}
$(document).ready(function(){
//initial layout
$("#gqbclassrestrictionsexist").hide();
$("#addFilterWindowOverlay").hide();
$("#filterbox #clear").hide();
$('#filter').droppable({
accept: '.show-property',
scope: 'Resource',
activeClass: 'ui-droppable-accepted-window',
hoverClass: 'ui-droppable-hovered',
drop:
function(event, ui) {
$("#property option:selected").each(function () {
$(this).attr('selected', false);
});
$("#property option[about="+$(ui.draggable).attr('about')+"]").attr('selected', true);
$("#property option:selected").each(updatePossibleValues);
showAddFilterBox();
}});
$("#addwindowhide").click(function(){
$.modal.close();
});
$("#addwindow #add").click( function(){
$.modal.close();
var prop = $("#addwindow #property option:selected").attr("about");
var propLabel = $("#addwindow #property option:selected").html();
var inverse = $("#addwindow #property option:selected").hasClass("InverseProperty");
var filtertype = $("#addwindow #resttype option:selected").html();
var negate = $("#negate").is(':checked');
var value1 = $("#addwindow #value1").val();
if(typeof value1 == "undefined"){
value1 = null;
}
var value2 = $("#addwindow #value2").val();
if(typeof value2 == "undefined"){
value2 = null;
}
var type = "literal";
var typedata = null;
// if value entering is possible but nothing entered: check if user selected something in the possible values box
if(value1 == "" && $("#valueboxes").children().length == 1){
if($("#addwindow #possiblevalues option:selected").length == 0){
return; // block add button
}
value1 = $("#addwindow #possiblevalues option:selected").attr("value");
filtertype = "equals";
type = $("#addwindow #possiblevalues option:selected").attr("type");
var language = $("#addwindow #possiblevalues option:selected").attr("language");
var datatype = $("#addwindow #possiblevalues option:selected").attr("datatype");
if(type == "literal" && typeof language != 'undefined'){
typedata = language;
} else if(type == "typed-literal"){
typedata = datatype;
}
}
filter.add("filterbox"+filter.counter, prop, inverse, propLabel, filtertype, value1, value2, type, typedata, function(newfilter) {
//react in filter box
//$("#addwindow").hide();
}, false, negate);
});
//show possible values for select property
$("#property").change(updatePossibleValues);
//different filter types need different value input fields
// bound: none
// contains, larger, smaller: one
// between: two - not implemented
// date: datepicker - not implemented
$("#resttype").change(function () {
var type = $("#resttype option:selected").val();
if(type == "contains" || type == "larger" || type == "smaller"){
if($("#valueboxes").children().length != 1){
$("#valueboxes").empty();
$("#valueboxes").append("");
}
}
if(type == "between"){
if($("#valueboxes").children().length != 2){
$("#valueboxes").empty();
$("#valueboxes").append("");
$("#valueboxes").append("");
}
}
if(type == "bound"){
if($("#valueboxes").children().length != 0){
$("#valueboxes").empty();
}
}
});
//$.dump(filter);
//register the filter box for (other) filter events
//filter.addCallback(function(newfilter){ showFilter() });
$('.filter .delete').click(function(){
filter.remove($(this).parents('.filter').attr('id'));
})
});
================================================
FILE: extensions/filter/resources/jquery.dump.js
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
jQuery.fn.dump = function(showTypes, showAttributes) {
jQuery.dump($(this), showTypes, showAttributes);
return this;
};
jQuery.dump = function(object, showTypes, showAttributes) {
var dump = '';
var st = typeof showTypes == 'undefined' ? true : showTypes;
var sa = typeof showAttributes == 'undefined' ? true : showAttributes;
var winName = 'dumpWin';
var w = 760;
var h = 500;
var leftPos = screen.width ? (screen.width - w) / 2 : 0;
var topPos = screen.height ? (screen.height - h) / 2 : 0;
var settings = 'height=' + h + ',width=' + w + ',top=' + topPos + ',left=' + leftPos + ',scrollbars=yes,menubar=yes,status=yes,resizable=yes';
var title = 'Dump';
var script = 'function tRow(s) {t = s.parentNode.lastChild;tTarget(t, tSource(s)) ;}function tTable(s) {var switchToState = tSource(s) ;var table = s.parentNode.parentNode;for (var i = 1; i < table.childNodes.length; i++) {t = table.childNodes[i] ;if (t.style) {tTarget(t, switchToState);}}}function tSource(s) {if (s.style.fontStyle == "italic" || s.style.fontStyle == null) {s.style.fontStyle = "normal";s.title = "click to collapse";return "open";} else {s.style.fontStyle = "italic";s.title = "click to expand";return "closed" ;}}function tTarget (t, switchToState) {if (switchToState == "open") {t.style.display = "";} else {t.style.display = "none";}}';
var _recurse = function (o, type) {
var i;
var j = 0;
var r = '';
type = _dumpType(o);
switch (type) {
case 'regexp':
var t = type;
r += '
' + t + '
';
r += '
RegExp:
' + o + '
';
j++;
break;
case 'date':
var t = type;
r += '
' + t + '
';
r += '
Date:
' + o + '
';
j++;
break;
case 'function':
var t = type;
var a = o.toString().match(/^.*function.*?\((.*?)\)/im);
var args = (a == null || typeof a[1] == 'undefined' || a[1] == '') ? 'none' : a[1];
r += '
' + t + '
';
r += '
Arguments:
' + args + '
Function:
' + o + '
';
j++;
break;
case 'domelement':
var t = type;
var attr = '';
if (sa) {
for (i in o) {if (!/innerHTML|outerHTML/i.test(i)) {attr += i + ': ' + o[i] + ' ';}}
}
r += '
' + t + '
';
r += '
Node Name:
' + o.nodeName.toLowerCase() + '
';
r += '
Node Type:
' + o.nodeType + '
';
r += '
Node Value:
' + o.nodeValue + '
';
if (sa) {
r += '
Attributes:
' + attr + '
';
r += '
innerHTML:
' + o.innerHTML + '
';
if (typeof o.outerHTML != 'undefined') {
r += '
outerHTML:
' + o.outerHTML + '
';
}
}
j++;
break;
}
if (/object|array/.test(type)) {
for (i in o) {
var t = _dumpType(o[i]);
if (j < 1) {
r += '
' + type + '
';
j++;
}
if (typeof o[i] == 'object' && o[i] != null) {
r += '
' + i + (st ? ' [' + t + ']' : '') + '
' + _recurse(o[i], t) + '
';
} else if (typeof o[i] == 'function') {
r += '
' + i + (st ? ' [' + t + ']' : '') + '
' + _recurse(o[i], t) + '
';
} else {
r += '
' + i + (st ? ' [' + t + ']' : '') + '
' + o[i] + '
';
}
}
}
if (j == 0) {
r += '
' + type + ' [empty]
';
}
r += '
';
return r;
};
var _dumpStyles = function(type, use) {
var r = '';
var table = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;cell-spacing:2px;';
var th = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;text-align:left;color: white;padding: 5px;vertical-align :top;cursor:hand;cursor:pointer;';
var td = 'font-size:xx-small;font-family:verdana,arial,helvetica,sans-serif;vertical-align:top;padding:3px;';
var thScript = 'onClick="tTable(this);" title="click to collapse"';
var tdScript = 'onClick="tRow(this);" title="click to collapse"';
switch (type) {
case 'string':
case 'number':
case 'boolean':
case 'undefined':
case 'object':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#0000cc;"';
break;
case 'th':
r = ' style="' + th + 'background-color:#4444cc;"' + thScript;
break;
case 'td-key':
r = ' style="' + td + 'background-color:#ccddff;cursor:hand;cursor:pointer;"' + tdScript;
break;
case 'td-value':
r = ' style="' + td + 'background-color:#fff;"';
break;
}
break;
case 'array':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#006600;"';
break;
case 'th':
r = ' style="' + th + 'background-color:#009900;"' + thScript;
break;
case 'td-key':
r = ' style="' + td + 'background-color:#ccffcc;cursor:hand;cursor:pointer;"' + tdScript;
break;
case 'td-value':
r = ' style="' + td + 'background-color:#fff;"';
break;
}
break;
case 'function':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#aa4400;"';
break;
case 'th':
r = ' style="' + th + 'background-color:#cc6600;"' + thScript;
break;
case 'td-key':
r = ' style="' + td + 'background-color:#fff;cursor:hand;cursor:pointer;"' + tdScript;
break;
case 'td-value':
r = ' style="' + td + 'background-color:#fff;"';
break;
}
break;
case 'arguments':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#dddddd;cell-spacing:3;"';
break;
case 'td-key':
r = ' style="' + th + 'background-color:#eeeeee;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
break;
}
break;
case 'regexp':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#CC0000;cell-spacing:3;"';
break;
case 'th':
r = ' style="' + th + 'background-color:#FF0000;"' + thScript;
break;
case 'td-key':
r = ' style="' + th + 'background-color:#FF5757;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
break;
case 'td-value':
r = ' style="' + td + 'background-color:#fff;"';
break;
}
break;
case 'date':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#663399;cell-spacing:3;"';
break;
case 'th':
r = ' style="' + th + 'background-color:#9966CC;"' + thScript;
break;
case 'td-key':
r = ' style="' + th + 'background-color:#B266FF;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
break;
case 'td-value':
r = ' style="' + td + 'background-color:#fff;"';
break;
}
break;
case 'domelement':
case 'document':
case 'window':
switch (use) {
case 'table':
r = ' style="' + table + 'background-color:#FFCC33;cell-spacing:3;"';
break;
case 'th':
r = ' style="' + th + 'background-color:#FFD966;"' + thScript;
break;
case 'td-key':
r = ' style="' + th + 'background-color:#FFF2CC;color:#000000;cursor:hand;cursor:pointer;"' + tdScript;
break;
case 'td-value':
r = ' style="' + td + 'background-color:#fff;"';
break;
}
break;
}
return r;
};
var _dumpType = function (obj) {
var t = typeof(obj);
if (t == 'function') {
var f = obj.toString();
if ( ( /^\/.*\/[gi]??[gi]??$/ ).test(f)) {
return 'regexp';
} else if ((/^\[object.*\]$/i ).test(f)) {
t = 'object'
}
}
if (t != 'object') {
return t;
}
switch (obj) {
case null:
return 'null';
case window:
return 'window';
case document:
return 'document';
case window.event:
return 'event';
}
if (window.event && (event.type == obj.type)) {
return 'event';
}
var c = obj.constructor;
if (c != null) {
switch(c) {
case Array:
t = 'array';
break;
case Date:
return 'date';
case RegExp:
return 'regexp';
case Object:
t = 'object';
break;
case ReferenceError:
return 'error';
default:
var sc = c.toString();
var m = sc.match(/\s*function (.*)\(/);
if (m != null) {
return 'object';
}
}
}
var nt = obj.nodeType;
if (nt != null) {
switch(nt) {
case 1:
return 'domelement';
case 3:
return 'string';
}
}
if (obj.toString != null) {
var ex = obj.toString();
var am = ex.match(/^\[object (.*)\]$/i);
if (am != null) {
var am = am[1];
switch(am.toLowerCase()) {
case 'event':
return 'event';
case 'nodelist':
case 'htmlcollection':
case 'elementarray':
return 'array';
case 'htmldocument':
return 'htmldocument';
}
}
}
return t;
};
dump += (/string|number|undefined|boolean/.test(typeof(object)) || object == null) ? object : _recurse(object, typeof object);
winName = window.open('', '', settings);
if (jQuery.browser.msie || jQuery.browser.browser == 'opera' || jQuery.browser.browser == 'safari') {
winName.document.write(' ' + title + ' ');
winName.document.write('' + dump + '');
} else {
winName.document.body.innerHTML = dump;
winName.document.title = title;
var ffs = winName.document.createElement('script');
ffs.setAttribute('type', 'text/javascript');
ffs.appendChild(document.createTextNode(script));
winName.document.getElementsByTagName('head')[0].appendChild(ffs);
}
winName.focus();
};
================================================
FILE: extensions/filter/resources/jquery.treeview.css
================================================
.treeview, .treeview ul {
padding: 0;
margin: 0;
list-style: none;
}
.treeview ul {
background-color: white;
margin-top: 4px;
}
.treeview .hitarea {
background: url(images/treeview-default.gif) -64px -25px no-repeat;
height: 16px;
width: 16px;
margin-left: -16px;
float: left;
cursor: pointer;
}
/* fix for IE6 */
* html .hitarea {
display: inline;
float:none;
}
.treeview li {
margin: 0;
padding: 3px 0pt 3px 16px;
}
.treeview a.selected {
background-color: #eee;
}
#treecontrol { margin: 1em 0; display: none; }
.treeview .hover { color: red; cursor: pointer; }
.treeview li { background: url(images/treeview-default-line.gif) 0 0 no-repeat; }
.treeview li.jqtvcollapsable, .treeview li.jqtvexpandable { background-position: 0 -176px; }
.treeview .expandable-hitarea { background-position: -80px -3px; }
.treeview li.last { background-position: 0 -1766px }
.treeview li.lastCollapsable, .treeview li.lastExpandable { background-image: url(images/treeview-default.gif); }
.treeview li.lastCollapsable { background-position: 0 -111px }
.treeview li.lastExpandable { background-position: -32px -67px }
.treeview div.lastCollapsable-hitarea, .treeview div.lastExpandable-hitarea { background-position: 0; }
.treeview-red li { background-image: url(images/treeview-red-line.gif); }
.treeview-red .hitarea, .treeview-red li.lastCollapsable, .treeview-red li.lastExpandable { background-image: url(images/treeview-red.gif); }
.treeview-black li { background-image: url(images/treeview-black-line.gif); }
.treeview-black .hitarea, .treeview-black li.lastCollapsable, .treeview-black li.lastExpandable { background-image: url(images/treeview-black.gif); }
.treeview-gray li { background-image: url(images/treeview-gray-line.gif); }
.treeview-gray .hitarea, .treeview-gray li.lastCollapsable, .treeview-gray li.lastExpandable { background-image: url(images/treeview-gray.gif); }
.treeview-famfamfam li { background-image: url(images/treeview-famfamfam-line.gif); }
.treeview-famfamfam .hitarea, .treeview-famfamfam li.lastCollapsable, .treeview-famfamfam li.lastExpandable { background-image: url(images/treeview-famfamfam.gif); }
.filetree li { padding: 3px 0 2px 16px; }
.filetree span.folder, .filetree span.file { padding: 1px 0 1px 16px; display: block; }
.filetree span.folder { background: url(images/folder.gif) 0 0 no-repeat; }
.filetree li.jqtvexpandable span.folder { background: url(images/folder-closed.gif) 0 0 no-repeat; }
.filetree span.file { background: url(images/file.gif) 0 0 no-repeat; cursor: move; }
================================================
FILE: extensions/filter/resources/jquery.treeview.js
================================================
/*
* Treeview 1.4 - jQuery plugin to hide and show branches of a tree
*
* http://bassistance.de/jquery-plugins/jquery-plugin-treeview/
* http://docs.jquery.com/Plugins/Treeview
*
* Copyright (c) 2007 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.treeview.js 4684 2008-02-07 19:08:06Z joern.zaefferer $
*
*/
;(function($) {
$.extend($.fn, {
swapClass: function(c1, c2) {
var c1Elements = this.filter('.' + c1);
this.filter('.' + c2).removeClass(c2).addClass(c1);
c1Elements.removeClass(c1).addClass(c2);
return this;
},
replaceClass: function(c1, c2) {
return this.filter('.' + c1).removeClass(c1).addClass(c2).end();
},
hoverClass: function(className) {
className = className || "hover";
return this.hover(function() {
$(this).addClass(className);
}, function() {
$(this).removeClass(className);
});
},
heightToggle: function(animated, callback) {
animated ?
this.animate({ height: "toggle" }, animated, callback) :
this.each(function(){
jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
if(callback)
callback.apply(this, arguments);
});
},
heightHide: function(animated, callback) {
if (animated) {
this.animate({ height: "hide" }, animated, callback);
} else {
this.hide();
if (callback)
this.each(callback);
}
},
prepareBranches: function(settings) {
if (!settings.prerendered) {
// mark last tree items
this.filter(":last-child:not(ul)").addClass(CLASSES.last);
// collapse whole tree, or only those marked as closed, anyway except those marked as open
this.filter((settings.collapsed ? "" : "." + CLASSES.closed) + ":not(." + CLASSES.open + ")").find(">ul").hide();
}
// return all items with sublists
return this.filter(":has(>ul)");
},
applyClasses: function(settings, toggler) {
this.filter(":has(>ul):not(:has(>a))").find(">span").click(function(event) {
toggler.apply($(this).next());
}).add( $("a", this) ).hoverClass();
if (!settings.prerendered) {
// handle closed ones first
this.filter(":has(>ul:hidden)")
.addClass(CLASSES.expandable)
.replaceClass(CLASSES.last, CLASSES.lastExpandable);
// handle open ones
this.not(":has(>ul:hidden)")
.addClass(CLASSES.collapsable)
.replaceClass(CLASSES.last, CLASSES.lastCollapsable);
// create hitarea
this.prepend("").find("div." + CLASSES.hitarea).each(function() {
var classes = "";
$.each($(this).parent().attr("class").split(" "), function() {
classes += this + "-hitarea ";
});
$(this).addClass( classes );
});
}
// apply event to hitarea
this.find("div." + CLASSES.hitarea).click( toggler );
},
treeview: function(settings) {
settings = $.extend({
cookieId: "treeview"
}, settings);
if (settings.add) {
return this.trigger("add", [settings.add]);
}
if ( settings.toggle ) {
var callback = settings.toggle;
settings.toggle = function() {
return callback.apply($(this).parent()[0], arguments);
};
}
// factory for treecontroller
function treeController(tree, control) {
// factory for click handlers
function handler(filter) {
return function() {
// reuse toggle event handler, applying the elements to toggle
// start searching for all hitareas
toggler.apply( $("div." + CLASSES.hitarea, tree).filter(function() {
// for plain toggle, no filter is provided, otherwise we need to check the parent element
return filter ? $(this).parent("." + filter).length : true;
}) );
return false;
};
}
// click on first element to collapse tree
$("a:eq(0)", control).click( handler(CLASSES.collapsable) );
// click on second to expand tree
$("a:eq(1)", control).click( handler(CLASSES.expandable) );
// click on third to toggle tree
$("a:eq(2)", control).click( handler() );
}
// handle toggle event
function toggler() {
$(this)
.parent()
// swap classes for hitarea
.find(">.hitarea")
.swapClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
.swapClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
.end()
// swap classes for parent li
.swapClass( CLASSES.collapsable, CLASSES.expandable )
.swapClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
// find child lists
.find( ">ul" )
// toggle them
.heightToggle( settings.animated, settings.toggle );
if ( settings.unique ) {
$(this).parent()
.siblings()
// swap classes for hitarea
.find(">.hitarea")
.replaceClass( CLASSES.collapsableHitarea, CLASSES.expandableHitarea )
.replaceClass( CLASSES.lastCollapsableHitarea, CLASSES.lastExpandableHitarea )
.end()
.replaceClass( CLASSES.collapsable, CLASSES.expandable )
.replaceClass( CLASSES.lastCollapsable, CLASSES.lastExpandable )
.find( ">ul" )
.heightHide( settings.animated, settings.toggle );
}
}
function serialize() {
function binary(arg) {
return arg ? 1 : 0;
}
var data = [];
branches.each(function(i, e) {
data[i] = $(e).is(":has(>ul:visible)") ? 1 : 0;
});
$.cookie(settings.cookieId, data.join("") );
}
function deserialize() {
var stored = $.cookie(settings.cookieId);
if ( stored ) {
var data = stored.split("");
branches.each(function(i, e) {
$(e).find(">ul")[ parseInt(data[i]) ? "show" : "hide" ]();
});
}
}
// add treeview class to activate styles
this.addClass("treeview");
// prepare branches and find all tree items with child lists
var branches = this.find("li").prepareBranches(settings);
switch(settings.persist) {
case "cookie":
var toggleCallback = settings.toggle;
settings.toggle = function() {
serialize();
if (toggleCallback) {
toggleCallback.apply(this, arguments);
}
};
deserialize();
break;
case "location":
var current = this.find("a").filter(function() { return this.href.toLowerCase() == location.href.toLowerCase(); });
if ( current.length ) {
current.addClass("selected").parents("ul, li").add( current.next() ).show();
}
break;
}
branches.applyClasses(settings, toggler);
// if control option is set, create the treecontroller and show it
if ( settings.control ) {
treeController(this, settings.control);
$(settings.control).show();
}
return this.bind("add", function(event, branches) {
$(branches).prev()
.removeClass(CLASSES.last)
.removeClass(CLASSES.lastCollapsable)
.removeClass(CLASSES.lastExpandable)
.find(">.hitarea")
.removeClass(CLASSES.lastCollapsableHitarea)
.removeClass(CLASSES.lastExpandableHitarea);
$(branches).find("li").andSelf().prepareBranches(settings).applyClasses(settings, toggler);
});
}
});
// classes used by the plugin
// need to be styled via external stylesheet, see first example
var CLASSES = $.fn.treeview.classes = {
open: "open",
closed: "closed",
expandable: "jqtvexpandable",
expandableHitarea: "expandable-hitarea",
lastExpandableHitarea: "lastExpandable-hitarea",
collapsable: "jqtvcollapsable",
collapsableHitarea: "collapsable-hitarea",
lastCollapsableHitarea: "lastCollapsable-hitarea",
lastCollapsable: "lastCollapsable",
lastExpandable: "lastExpandable",
last: "last",
hitarea: "hitarea"
};
// provide backwards compability
$.fn.Treeview = $.fn.treeview;
})(jQuery);
================================================
FILE: extensions/filter/templates/filter/complexfilter.phtml
================================================
================================================
FILE: extensions/literaltypes/LiteraltypesPlugin.php
================================================
getParams();
if (!empty($parameter['datatype'])) {
$url = new OntoWiki_Url(array('route' => 'properties'), array('r'));
$url->setParam('r', $parameter['datatype'], true);
$datatypeLink
= ""
. (OntoWiki_Utils::getUriLocalPart($parameter['datatype'])) . "";
$ret = "" . $parameter['value'] . "";
$ret .= "[" . $datatypeLink . "]";
return $ret;
}
if (!empty($parameter['language'])) {
$ret = "" . $parameter['value'] . "";
$ret .= "[" . $parameter['language'] . "]";
return $ret;
}
}
}
================================================
FILE: extensions/literaltypes/default.ini
================================================
enabled = false
name = LiteralTypes
description = "Visualizes the language or the datatype of a LiteralValue"
author = "Michael Martin"
[events]
1 = onDisplayLiteralPropertyValue
[private]
================================================
FILE: extensions/literaltypes/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :literaltypes .
:literaltypes a doap:Project ;
doap:name "literaltypes" ;
owconfig:privateNamespace ;
owconfig:enabled "false"^^xsd:boolean ;
rdfs:label "LiteralTypes" ;
doap:description "Visualizes the language or the datatype of a LiteralValue" ;
owconfig:authorLabel "Michael Martin" ;
owconfig:pluginEvent event:onDisplayLiteralPropertyValue ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/mail/MailPlugin.php
================================================
registry->registerJob(
'testMail',
'extensions/mail/jobs/Mail.php',
'Mail_Job_Mail',
$this->_privateConfig->smtp->toArray()
);
}
}
================================================
FILE: extensions/mail/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :mail .
:mail a doap:Project ;
doap:name "mail" ;
owconfig:privateNamespace ;
owconfig:enabled "false"^^xsd:boolean ;
rdfs:label "Mail" ;
doap:description "A plug-in that tests mail support" ;
owconfig:authorLabel "Würker Christian" ;
owconfig:pluginEvent event:onAnnounceWorker ;
owconfig:config [
a owconfig:Config;
owconfig:id "smtp";
:server "yourserver.de";
:auth "login";
:username "user@yourserver.de";
:password "";
] ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/mail/jobs/Mail.php
================================================
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class Mail_Job_Mail extends Erfurt_Worker_Job_Abstract
{
/**
* Send mail.
*
* @access public
* @param object $workload Object with mail sender, receiver, subject and body
* @return void
* @throws InvalidArgumentException if workload object has no sender
* @throws InvalidArgumentException if workload object has no receiver
* @throws InvalidArgumentException if workload object has no subject
* @throws InvalidArgumentException if workload object has no body
*/
public function run($workload)
{
$smtpServer = $this->options['server'];
$config = array();
if ($this->options['auth']) {
$config['auth'] = $this->options['auth'];
$config['username'] = $this->options['username'];
$config['password'] = $this->options['password'];
}
$transport = new Zend_Mail_Transport_Smtp($smtpServer, $config);
if (is_object($workload)) {
if (empty($workload->sender)) {
throw new InvalidArgumentException('Workload is missing sender');
}
if (empty($workload->receiver)) {
throw new InvalidArgumentException('Workload is missing receiver');
}
if (empty($workload->subject)) {
throw new InvalidArgumentException('Workload is missing subject');
}
if (empty($workload->body)) {
throw new InvalidArgumentException('Workload is missing body');
}
$mail = new Zend_Mail();
$mail->setDefaultTransport($transport);
$mail->addTo($workload->receiver);
$mail->setSubject($workload->subject);
$mail->setBodyText($workload->body);
$mail->setFrom($workload->sender);
$mail->send($transport);
$this->logSuccess('Mail "'.$workload->subject.'" sent to '.$workload->receiver);
}
}
}
================================================
FILE: extensions/mailtolink/MailtolinkPlugin.php
================================================
_privateConfig->properties->toArray();
$this->_properties = array_combine($configValues, $configValues);
return $this->_properties;
}
public function onDisplayObjectPropertyValue($event)
{
if (!substr($event->value, 0, 7) === 'mailto:') {
$mailUri = 'mailto:' . $event->value;
} else {
$mailUri = $event->value;
}
if (isset($this->_properties[$event->property])) {
return '' . $event->value . '';
}
}
public function onDisplayLiteralPropertyValue($event)
{
if (!substr($event->value, 0, 7) === 'mailto:') {
$mailUri = 'mailto:' . $event->value;
} else {
$mailUri = $event->value;
}
if (isset($this->_properties[$event->property])) {
return '' . $event->value . '';
}
}
}
================================================
FILE: extensions/mailtolink/default.ini
================================================
enabled = yes
name = Mailtolink
description = "A plug-in that renders values of certain properties as mailto links."
author = "Norman Heino"
; url =
[events]
1 = onDisplayObjectPropertyValue
2 = onDisplayLiteralPropertyValue
[private]
properties[] = "http://xmlns.com/foaf/0.1/mbox"
properties[] = "http://swrc.ontoware.org/ontology#email"
================================================
FILE: extensions/mailtolink/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :mailtolink .
:mailtolink a doap:Project ;
doap:name "mailtolink" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Mailtolink" ;
doap:description "A plug-in that renders values of certain properties as mailto links." ;
owconfig:authorLabel "Norman Heino" ;
owconfig:pluginEvent event:onDisplayObjectPropertyValue ;
owconfig:pluginEvent event:onDisplayLiteralPropertyValue ;
:properties ;
:properties ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/manchester/ManchesterController.php
================================================
_helper->viewRenderer->setNoRender();
// disable layout for Ajax requests
$this->_helper->layout()->disableLayout();
$response = $this->getResponse();
$request = $this->_request;
$output = false;
try {
$model = $this->_owApp->selectedModel;
$store = $this->_owApp->erfurt->getStore();
$classname = OntoWiki::getInstance()->selectedResource;
$manchester = $request->manchester;
$structuredOwl = $this->initParser($manchester);
$triples = $structuredOwl->toTriples();
$output = array(
'message' => 'class saved',
'class' => 'success',
'out' => $triples
);
} catch (Exception $e) {
// encode the exception for http response
$output = array(
'message' => $e->getMessage(),
'class' => 'error'
);
$response->setRawHeader('HTTP/1.1 500 Internal Server Error');
}
// send the response
$response->setHeader('Content-Type', 'application/json');
$response->setBody(json_encode($output));
}
private function initParser($inputQuery)
{
require_once 'antlr/Php/antlr.php';
$input = new ANTLRStringStream($inputQuery);
$lexer = new Erfurt_Syntax_ManchesterLexer($input);
$tokens = new CommonTokenStream($lexer);
$parser = new Erfurt_Syntax_ManchesterParser($tokens);
// call the correct parser method (currently it's classFrame)
return $parser->classFrame();
}
}
================================================
FILE: extensions/manchester/ManchesterModule.php
================================================
selectedResource)) {
return;
}
}
/**
* Returns the content
*/
public function getContents()
{
$from = $this->_owApp->selectedModel;
$classname = OntoWiki::getInstance()->selectedResource;
$structured = Erfurt_Owl_Structured_Util_Owl2Structured::mapOWL2Structured(
array((string)$from), (string)$classname
);
$data = new StdClass();
$formUrl = new OntoWiki_Url(array('controller' => 'manchester', 'action' => 'post'), array());
$data->formUrl = (string)$formUrl;
$data->manchesterString = (string)$structured;
$content = $this->render('modules/manchester', $data, 'data');
return $content;
}
}
================================================
FILE: extensions/manchester/default.ini
================================================
;;
; Basic component configuration
;;
enabled = false
templates = "templates"
languages = "languages"
name = "Manchester"
description = "Class Editor with Manchester Syntax"
author = "AKSW"
modules.manchester.title = "Manchester Syntax"
modules.manchester.caching = no
modules.manchester.priority = 3
modules.manchester.contexts.0 = "main.window.properties"
================================================
FILE: extensions/manchester/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :manchester .
:manchester a doap:Project ;
doap:name "manchester" ;
owconfig:privateNamespace ;
owconfig:enabled "false"^^xsd:boolean ;
owconfig:templates "templates" ;
owconfig:languages "languages" ;
rdfs:label "Manchester" ;
doap:description "Class Editor with Manchester Syntax" ;
owconfig:authorLabel "AKSW" ;
owconfig:hasModule :Manchester .
:Manchester a owconfig:Module ;
rdfs:label "Manchester Syntax" ;
owconfig:caching "false"^^xsd:boolean ;
owconfig:priority "3" ;
owconfig:context "main.window.properties" .
:manchester doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/manchester/templates/modules/manchester.phtml
================================================
data ?>
================================================
FILE: extensions/markdown/MarkdownPlugin.php
================================================
properties = array_values($this->_privateConfig->properties->toArray());
if (isset($this->_privateConfig->datatypes) && $this->_privateConfig->datatypes instanceof Zend_Config) {
$this->datatypes = array_values($this->_privateConfig->datatypes->toArray());
} else {
if (isset($this->_privateConfig->datatypes)) {
$this->datatypes = array($this->_privateConfig->datatypes);
}
}
}
public function onDisplayLiteralPropertyValue($event)
{
if (in_array($event->property, $this->properties)) {
require_once 'parser/markdown.php';
return Markdown($event->value);
}
if (in_array($event->datatype, $this->datatypes)) {
require_once 'parser/markdown.php';
return Markdown($event->value);
}
}
}
================================================
FILE: extensions/markdown/default.ini
================================================
enabled = true
name = Markdown
description = "A plug-in that renders markdown values of certain properties as html."
author = "Marvin Frommhold"
; url =
[events]
1 = onDisplayLiteralPropertyValue
[private]
properties[] = "http://purl.org/dc/elements/1.1/description"
properties[] = "http://rdfs.org/sioc/ns#content"
datatypes[] = "http://ns.ontowiki.net/SysOnt/Markdown"
================================================
FILE: extensions/markdown/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :markdown .
:markdown a doap:Project ;
doap:name "markdown" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Markdown" ;
doap:description "A plug-in that renders markdown values of certain properties as html." ;
owconfig:authorLabel "Marvin Frommhold" ;
owconfig:pluginEvent event:onDisplayLiteralPropertyValue ;
:properties ;
:properties ;
:datatypes ;
doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/markdown/parser/License.text
================================================
PHP Markdown
Copyright (c) 2004-2013 Michel Fortin
All rights reserved.
Based on Markdown
Copyright (c) 2003-2006 John Gruber
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.
================================================
FILE: extensions/markdown/parser/PHP Markdown Readme.text
================================================
PHP Markdown
============
Version 1.0.1p - Sun 13 Jan 2013
by Michel Fortin
based on work by John Gruber
Introduction
------------
Markdown is a text-to-HTML conversion tool for web writers. Markdown
allows you to write using an easy-to-read, easy-to-write plain text
format, then convert it to structurally valid XHTML (or HTML).
"Markdown" is two things: a plain text markup syntax, and a software
tool, written in Perl, that converts the plain text markup to HTML.
PHP Markdown is a port to PHP of the original Markdown program by
John Gruber.
PHP Markdown can work as a plug-in for WordPress, as a modifier for
the Smarty templating engine, or as a replacement for Textile
formatting in any software that supports Textile.
Full documentation of Markdown's syntax is available on John's
Markdown page:
Installation and Requirement
----------------------------
PHP Markdown requires PHP version 4.0.5 or later.
Before PHP 5.3.7, pcre.backtrack_limit defaults to 100 000, which is too small
in many situations. You might need to set it to higher values. Later PHP
releases defaults to 1 000 000, which is usually fine.
### WordPress ###
PHP Markdown works with [WordPress][wp], version 1.2 or later.
[wp]: http://wordpress.org/
1. To use PHP Markdown with WordPress, place the "markdown.php" file
in the "plugins" folder. This folder is located inside
"wp-content" at the root of your site:
(site home)/wp-content/plugins/
2. Activate the plugin with the administrative interface of
WordPress. In the "Plugins" section you will now find Markdown.
To activate the plugin, click on the "Activate" button on the
same line as Markdown. Your entries will now be formatted by
PHP Markdown.
3. To post Markdown content, you'll first have to disable the
"visual" editor in the User section of WordPress.
You can configure PHP Markdown to not apply to the comments on your
WordPress weblog. See the "Configuration" section below.
It is not possible at this time to apply a different set of
filters to different entries. All your entries will be formatted by
PHP Markdown. This is a limitation of WordPress. If your old entries
are written in HTML (as opposed to another formatting syntax, like
Textile), they'll probably stay fine after installing Markdown.
### Replacing Textile in TextPattern ###
[TextPattern][tp] use [Textile][tx] to format your text. You can
replace Textile by Markdown in TextPattern without having to change
any code by using the *Textile Compatibility Mode*. This may work
with other software that expect Textile too.
[tx]: http://www.textism.com/tools/textile/
[tp]: http://www.textpattern.com/
1. Rename the "markdown.php" file to "classTextile.php". This will
make PHP Markdown behave as if it was the actual Textile parser.
2. Replace the "classTextile.php" file TextPattern installed in your
web directory. It can be found in the "lib" directory:
(site home)/textpattern/lib/
Contrary to Textile, Markdown does not convert quotes to curly ones
and does not convert multiple hyphens (`--` and `---`) into en- and
em-dashes. If you use PHP Markdown in Textile Compatibility Mode, you
can solve this problem by installing the "smartypants.php" file from
[PHP SmartyPants][psp] beside the "classTextile.php" file. The Textile
Compatibility Mode function will use SmartyPants automatically without
further modification.
[psp]: http://michelf.ca/projects/php-smartypants/
### Updating Markdown in Other Programs ###
Many web applications now ship with PHP Markdown, or have plugins to
perform the conversion to HTML. You can update PHP Markdown in many of
these programs by swapping the old "markdown.php" file for the new one.
Here is a short non-exhaustive list of some programs and where they
hide the "markdown.php" file.
| Program | Path to Markdown
| ------- | ----------------
| [Pivot][] | `(site home)/pivot/includes/markdown/markdown.php`
If you're unsure if you can do this with your application, ask the
developer, or wait for the developer to update his application or
plugin with the new version of PHP Markdown.
[Pivot]: http://pivotlog.net/
### In Your Own Programs ###
You can use PHP Markdown easily in your current PHP program. Simply
include the file and then call the Markdown function on the text you
want to convert:
include_once "markdown.php";
$my_html = Markdown($my_text);
If you wish to use PHP Markdown with another text filter function
built to parse HTML, you should filter the text *after* the Markdown
function call. This is an example with [PHP SmartyPants][psp]:
$my_html = SmartyPants(Markdown($my_text));
### With Smarty ###
If your program use the [Smarty][sm] template engine, PHP Markdown
can now be used as a modifier for your templates. Rename "markdown.php"
to "modifier.markdown.php" and put it in your smarty plugins folder.
[sm]: http://smarty.php.net/
If you are using MovableType 3.1 or later, the Smarty plugin folder is
located at `(MT CGI root)/php/extlib/smarty/plugins`. This will allow
Markdown to work on dynamic pages.
Configuration
-------------
By default, PHP Markdown produces XHTML output for tags with empty
elements. E.g.:
Markdown can be configured to produce HTML-style tags; e.g.:
To do this, you must edit the "MARKDOWN_EMPTY_ELEMENT_SUFFIX"
definition below the "Global default settings" header at the start of
the "markdown.php" file.
### WordPress-Specific Settings ###
By default, the Markdown plugin applies to both posts and comments on
your WordPress weblog. To deactivate one or the other, edit the
`MARKDOWN_WP_POSTS` or `MARKDOWN_WP_COMMENTS` definitions under the
"WordPress settings" header at the start of the "markdown.php" file.
Bugs
----
To file bug reports please send email to:
Please include with your report: (1) the example input; (2) the output you
expected; (3) the output PHP Markdown actually produced.
If you have a problem where Markdown gives you an empty result, first check
that the backtrack limit is not too low by running `php --info | grep pcre`.
See Installation and Requirement above for details.
Version History
---------------
1.0.1p (13 Jan 2013):
* Fixed an issue where some XML-style empty tags (such as ` `) were not
recognized correctly as such when inserted into Markdown-formatted text.
* The following HTML 5 elements are treated as block elements when at the
root of an HTML block: `article`, `section`, `nav`, `aside`, `hgroup`,
`header`, `footer`, and `figure`. `svg` too.
1.0.1o (8 Jan 2012):
* Silenced a new warning introduced around PHP 5.3 complaining about
POSIX characters classes not being implemented. PHP Markdown does not
use POSIX character classes, but it nevertheless trigged that warning.
1.0.1n (10 Oct 2009):
* Enabled reference-style shortcut links. Now you can write reference-style
links with less brakets:
This is [my website].
[my website]: http://example.com/
This was added in the 1.0.2 betas, but commented out in the 1.0.1 branch,
waiting for the feature to be officialized. [But half of the other Markdown
implementations are supporting this syntax][half], so it makes sense for
compatibility's sake to allow it in PHP Markdown too.
[half]: http://babelmark.bobtfish.net/?markdown=This+is+%5Bmy+website%5D.%0D%0A%09%09%0D%0A%5Bmy+website%5D%3A+http%3A%2F%2Fexample.com%2F%0D%0A&src=1&dest=2
* Now accepting many valid email addresses in autolinks that were
previously rejected, such as:
<"abc@def"@example.com>
<"Fred Bloggs"@example.com>
* Now accepting spaces in URLs for inline and reference-style links. Such
URLs need to be surrounded by angle brakets. For instance:
[link text]( "optional title")
[link text][ref]
[ref]: "optional title"
There is still a quirk which may prevent this from working correctly with
relative URLs in inline-style links however.
* Fix for adjacent list of different kind where the second list could
end as a sublist of the first when not separated by an empty line.
* Fixed a bug where inline-style links wouldn't be recognized when the link
definition contains a line break between the url and the title.
* Fixed a bug where tags where the name contains an underscore aren't parsed
correctly.
* Fixed some corner-cases mixing underscore-ephasis and asterisk-emphasis.
1.0.1m (21 Jun 2008):
* Lists can now have empty items.
* Rewrote the emphasis and strong emphasis parser to fix some issues
with odly placed and overlong markers.
1.0.1l (11 May 2008):
* Now removing the UTF-8 BOM at the start of a document, if present.
* Now accepting capitalized URI schemes (such as HTTP:) in automatic
links, such as ``.
* Fixed a problem where `` was seen as a horizontal
rule instead of an automatic link.
* Fixed an issue where some characters in Markdown-generated HTML
attributes weren't properly escaped with entities.
* Fix for code blocks as first element of a list item. Previously,
this didn't create any code block for item 2:
* Item 1 (regular paragraph)
* Item 2 (code block)
* A code block starting on the second line of a document wasn't seen
as a code block. This has been fixed.
* Added programatically-settable parser properties `predef_urls` and
`predef_titles` for predefined URLs and titles for reference-style
links. To use this, your PHP code must call the parser this way:
$parser = new Markdwon_Parser;
$parser->predef_urls = array('linkref' => 'http://example.com');
$html = $parser->transform($text);
You can then use the URL as a normal link reference:
[my link][linkref]
[my link][linkRef]
Reference names in the parser properties *must* be lowercase.
Reference names in the Markdown source may have any case.
* Added `setup` and `teardown` methods which can be used by subclassers
as hook points to arrange the state of some parser variables before and
after parsing.
1.0.1k (26 Sep 2007):
* Fixed a problem introduced in 1.0.1i where three or more identical
uppercase letters, as well as a few other symbols, would trigger
a horizontal line.
1.0.1j (4 Sep 2007):
* Fixed a problem introduced in 1.0.1i where the closing `code` and
`pre` tags at the end of a code block were appearing in the wrong
order.
* Overriding configuration settings by defining constants from an
external before markdown.php is included is now possible without
producing a PHP warning.
1.0.1i (31 Aug 2007):
* Fixed a problem where an escaped backslash before a code span
would prevent the code span from being created. This should now
work as expected:
Litteral backslash: \\`code span`
* Overall speed improvements, especially with long documents.
1.0.1h (3 Aug 2007):
* Added two properties (`no_markup` and `no_entities`) to the parser
allowing HTML tags and entities to be disabled.
* Fix for a problem introduced in 1.0.1g where posting comments in
WordPress would trigger PHP warnings and cause some markup to be
incorrectly filtered by the kses filter in WordPress.
1.0.1g (3 Jul 2007):
* Fix for PHP 5 compiled without the mbstring module. Previous fix to
calculate the length of UTF-8 strings in `detab` when `mb_strlen` is
not available was only working with PHP 4.
* Fixed a problem with WordPress 2.x where full-content posts in RSS feeds
were not processed correctly by Markdown.
* Now supports URLs containing literal parentheses for inline links
and images, such as:
[WIMP](http://en.wikipedia.org/wiki/WIMP_(computing))
Such parentheses may be arbitrarily nested, but must be
balanced. Unbalenced parentheses are allowed however when the URL
when escaped or when the URL is enclosed in angle brakets `<>`.
* Fixed a performance problem where the regular expression for strong
emphasis introduced in version 1.0.1d could sometime be long to process,
give slightly wrong results, and in some circumstances could remove
entirely the content for a whole paragraph.
* Some change in version 1.0.1d made possible the incorrect nesting of
anchors within each other. This is now fixed.
* Fixed a rare issue where certain MD5 hashes in the content could
be changed to their corresponding text. For instance, this:
The MD5 value for "+" is "26b17225b626fb9238849fd60eabdf60".
was incorrectly changed to this in previous versions of PHP Markdown:
The MD5 value for "+" is "+".
* Now convert escaped characters to their numeric character
references equivalent.
This fix an integration issue with SmartyPants and backslash escapes.
Since Markdown and SmartyPants have some escapable characters in common,
it was sometime necessary to escape them twice. Previously, two
backslashes were sometime required to prevent Markdown from "eating" the
backslash before SmartyPants sees it:
Here are two hyphens: \\--
Now, only one backslash will do:
Here are two hyphens: \--
1.0.1f (7 Feb 2007):
* Fixed an issue with WordPress where manually-entered excerpts, but
not the auto-generated ones, would contain nested paragraphs.
* Fixed an issue introduced in 1.0.1d where headers and blockquotes
preceded too closely by a paragraph (not separated by a blank line)
where incorrectly put inside the paragraph.
* Fixed an issue introduced in 1.0.1d in the tokenizeHTML method where
two consecutive code spans would be merged into one when together they
form a valid tag in a multiline paragraph.
* Fixed an long-prevailing issue where blank lines in code blocks would
be doubled when the code block is in a list item.
This was due to the list processing functions relying on artificially
doubled blank lines to correctly determine when list items should
contain block-level content. The list item processing model was thus
changed to avoid the need for double blank lines.
* Fixed an issue with `<% asp-style %>` instructions used as inline
content where the opening `<` was encoded as `<`.
* Fixed a parse error occuring when PHP is configured to accept
ASP-style delimiters as boundaries for PHP scripts.
* Fixed a bug introduced in 1.0.1d where underscores in automatic links
got swapped with emphasis tags.
1.0.1e (28 Dec 2006)
* Added support for internationalized domain names for email addresses in
automatic link. Improved the speed at which email addresses are converted
to entities. Thanks to Milian Wolff for his optimisations.
* Made deterministic the conversion to entities of email addresses in
automatic links. This means that a given email address will always be
encoded the same way.
* PHP Markdown will now use its own function to calculate the length of an
UTF-8 string in `detab` when `mb_strlen` is not available instead of
giving a fatal error.
1.0.1d (1 Dec 2006)
* Fixed a bug where inline images always had an empty title attribute. The
title attribute is now present only when explicitly defined.
* Link references definitions can now have an empty title, previously if the
title was defined but left empty the link definition was ignored. This can
be useful if you want an empty title attribute in images to hide the
tooltip in Internet Explorer.
* Made `detab` aware of UTF-8 characters. UTF-8 multi-byte sequences are now
correctly mapped to one character instead of the number of bytes.
* Fixed a small bug with WordPress where WordPress' default filter `wpautop`
was not properly deactivated on comment text, resulting in hard line breaks
where Markdown do not prescribes them.
* Added a `TextileRestrited` method to the textile compatibility mode. There
is no restriction however, as Markdown does not have a restricted mode at
this point. This should make PHP Markdown work again in the latest
versions of TextPattern.
* Converted PHP Markdown to a object-oriented design.
* Changed span and block gamut methods so that they loop over a
customizable list of methods. This makes subclassing the parser a more
interesting option for creating syntax extensions.
* Also added a "document" gamut loop which can be used to hook document-level
methods (like for striping link definitions).
* Changed all methods which were inserting HTML code so that they now return
a hashed representation of the code. New methods `hashSpan` and `hashBlock`
are used to hash respectivly span- and block-level generated content. This
has a couple of significant effects:
1. It prevents invalid nesting of Markdown-generated elements which
could occur occuring with constructs like `*something [link*][1]`.
2. It prevents problems occuring with deeply nested lists on which
paragraphs were ill-formed.
3. It removes the need to call `hashHTMLBlocks` twice during the the
block gamut.
Hashes are turned back to HTML prior output.
* Made the block-level HTML parser smarter using a specially-crafted regular
expression capable of handling nested tags.
* Solved backtick issues in tag attributes by rewriting the HTML tokenizer to
be aware of code spans. All these lines should work correctly now:
barbar
``
* Changed the parsing of HTML comments to match simply from ``
instead using of the more complicated SGML-style rule with paired `--`.
This is how most browsers parse comments and how XML defines them too.
* `` has been added to the list of block-level elements and is now
treated as an HTML block instead of being wrapped within paragraph tags.
* Now only trim trailing newlines from code blocks, instead of trimming
all trailing whitespace characters.
* Fixed bug where this:
[text](http://m.com "title" )
wasn't working as expected, because the parser wasn't allowing for spaces
before the closing paren.
* Filthy hack to support markdown='1' in div tags.
* _DoAutoLinks() now supports the 'dict://' URL scheme.
* PHP- and ASP-style processor instructions are now protected as
raw HTML blocks.
... ?>
<% ... %>
* Fix for escaped backticks still triggering code spans:
There are two raw backticks here: \` and here: \`, not a code span
1.0.1c (9 Dec 2005)
* Fixed a problem occurring with PHP 5.1.1 due to a small
change to strings variable replacement behaviour in
this version.
1.0.1b (6 Jun 2005)
* Fixed a bug where an inline image followed by a reference link would
give a completely wrong result.
* Fix for escaped backticks still triggering code spans:
There are two raw backticks here: \` and here: \`, not a code span
* Fix for an ordered list following an unordered list, and the
reverse. There is now a loop in _DoList that does the two
separately.
* Fix for nested sub-lists in list-paragraph mode. Previously we got
a spurious extra level of `
` tags for something like this:
* this
* sub
that
* Fixed some incorrect behaviour with emphasis. This will now work
as it should:
*test **thing***
**test *thing***
***thing* test**
***thing** test*
Name: __________
Address: _______
* Correct a small bug in `_TokenizeHTML` where a Doctype declaration
was not seen as HTML.
* Major rewrite of the WordPress integration code that should
correct many problems by preventing default WordPress filters from
tampering with Markdown-formatted text. More details here:
1.0.1a (15 Apr 2005)
* Fixed an issue where PHP warnings were trigged when converting
text with list items running on PHP 4.0.6. This was comming from
the `rtrim` function which did not support the second argument
prior version 4.1. Replaced by a regular expression.
* Markdown now filter correctly post excerpts and comment
excerpts in WordPress.
* Automatic links and some code sample were "corrected" by
the balenceTag filter in WordPress meant to ensure HTML
is well formed. This new version of PHP Markdown postpone this
filter so that it runs after Markdown.
* Blockquote syntax and some code sample were stripped by
a new WordPress 1.5 filter meant to remove unwanted HTML
in comments. This new version of PHP Markdown postpone this
filter so that it runs after Markdown.
1.0.1 (16 Dec 2004):
* Changed the syntax rules for code blocks and spans. Previously,
backslash escapes for special Markdown characters were processed
everywhere other than within inline HTML tags. Now, the contents of
code blocks and spans are no longer processed for backslash escapes.
This means that code blocks and spans are now treated literally,
with no special rules to worry about regarding backslashes.
**IMPORTANT**: This breaks the syntax from all previous versions of
Markdown. Code blocks and spans involving backslash characters will
now generate different output than before.
Implementation-wise, this change was made by moving the call to
`_EscapeSpecialChars()` from the top-level `Markdown()` function to
within `_RunSpanGamut()`.
* Significants performance improvement in `_DoHeader`, `_Detab`
and `_TokenizeHTML`.
* Added `>`, `+`, and `-` to the list of backslash-escapable
characters. These should have been done when these characters
were added as unordered list item markers.
* Inline links using `<` and `>` URL delimiters weren't working:
like [this]()
Fixed by moving `_DoAutoLinks()` after `_DoAnchors()` in
`_RunSpanGamut()`.
* Fixed bug where auto-links were being processed within code spans:
like this: ``
Fixed by moving `_DoAutoLinks()` from `_RunBlockGamut()` to
`_RunSpanGamut()`.
* Sort-of fixed a bug where lines in the middle of hard-wrapped
paragraphs, which lines look like the start of a list item,
would accidentally trigger the creation of a list. E.g. a
paragraph that looked like this:
I recommend upgrading to version
8. Oops, now this line is treated
as a sub-list.
This is fixed for top-level lists, but it can still happen for
sub-lists. E.g., the following list item will not be parsed
properly:
* I recommend upgrading to version
8. Oops, now this line is treated
as a sub-list.
Given Markdown's list-creation rules, I'm not sure this can
be fixed.
* Fix for horizontal rules preceded by 2 or 3 spaces or followed by
trailing spaces and tabs.
* Standalone HTML comments are now handled; previously, they'd get
wrapped in a spurious `
` tag.
* `_HashHTMLBlocks()` now tolerates trailing spaces and tabs following
HTML comments and `
` tags.
* Changed special case pattern for hashing `` tags in
`_HashHTMLBlocks()` so that they must occur within three spaces
of left margin. (With 4 spaces or a tab, they should be
code blocks, but weren't before this fix.)
* Auto-linked email address can now optionally contain
a 'mailto:' protocol. I.e. these are equivalent:
* Fixed annoying bug where nested lists would wind up with
spurious (and invalid) `
` tags.
* Changed `_StripLinkDefinitions()` so that link definitions must
occur within three spaces of the left margin. Thus if you indent
a link definition by four spaces or a tab, it will now be a code
block.
* You can now write empty links:
[like this]()
and they'll be turned into anchor tags with empty href attributes.
This should have worked before, but didn't.
* `***this***` and `___this___` are now turned into
this
Instead of
this
which isn't valid.
* Fixed problem for links defined with urls that include parens, e.g.:
[1]: http://sources.wikipedia.org/wiki/Middle_East_Policy_(Chomsky)
"Chomsky" was being erroneously treated as the URL's title.
* Double quotes in the title of an inline link used to give strange
results (incorrectly made entities). Fixed.
* Tabs are now correctly changed into spaces. Previously, only
the first tab was converted. In code blocks, the second one was too,
but was not always correctly aligned.
* Fixed a bug where a tab character inserted after a quote on the same
line could add a slash before the quotes.
This is "before" [tab] and "after" a tab.
Previously gave this result:
This is \"before\" [tab] and "after" a tab.
* Removed a call to `htmlentities`. This fixes a bug where multibyte
characters present in the title of a link reference could lead to
invalid utf-8 characters.
* Changed a regular expression in `_TokenizeHTML` that could lead to
a segmentation fault with PHP 4.3.8 on Linux.
* Fixed some notices that could show up if PHP error reporting
E_NOTICE flag was set.
Copyright and License
---------------------
PHP Markdown
Copyright (c) 2004-2013 Michel Fortin
All rights reserved.
Based on Markdown
Copyright (c) 2003-2006 John Gruber
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.
================================================
FILE: extensions/markdown/parser/markdown.php
================================================
#
# Original Markdown
# Copyright (c) 2004-2006 John Gruber
#
#
define( 'MARKDOWN_VERSION', "1.0.1p" ); # Sun 13 Jan 2013
#
# Global default settings:
#
# Change to ">" for HTML output
@define( 'MARKDOWN_EMPTY_ELEMENT_SUFFIX', " />");
# Define the width of a tab for code blocks.
@define( 'MARKDOWN_TAB_WIDTH', 4 );
#
# WordPress settings:
#
# Change to false to remove Markdown from posts and/or comments.
@define( 'MARKDOWN_WP_POSTS', true );
@define( 'MARKDOWN_WP_COMMENTS', true );
### Standard Function Interface ###
@define( 'MARKDOWN_PARSER_CLASS', 'Markdown_Parser' );
function Markdown($text) {
#
# Initialize the parser and return the result of its transform method.
#
# Setup static parser variable.
static $parser;
if (!isset($parser)) {
$parser_class = MARKDOWN_PARSER_CLASS;
$parser = new $parser_class;
}
# Transform text using parser.
return $parser->transform($text);
}
### WordPress Plugin Interface ###
/*
Plugin Name: Markdown
Plugin URI: http://michelf.ca/projects/php-markdown/
Description: Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...
Version: 1.0.1p
Author: Michel Fortin
Author URI: http://michelf.ca/
*/
if (isset($wp_version)) {
# More details about how it works here:
#
# Post content and excerpts
# - Remove WordPress paragraph generator.
# - Run Markdown on excerpt, then remove all tags.
# - Add paragraph tag around the excerpt, but remove it for the excerpt rss.
if (MARKDOWN_WP_POSTS) {
remove_filter('the_content', 'wpautop');
remove_filter('the_content_rss', 'wpautop');
remove_filter('the_excerpt', 'wpautop');
add_filter('the_content', 'Markdown', 6);
add_filter('the_content_rss', 'Markdown', 6);
add_filter('get_the_excerpt', 'Markdown', 6);
add_filter('get_the_excerpt', 'trim', 7);
add_filter('the_excerpt', 'mdwp_add_p');
add_filter('the_excerpt_rss', 'mdwp_strip_p');
remove_filter('content_save_pre', 'balanceTags', 50);
remove_filter('excerpt_save_pre', 'balanceTags', 50);
add_filter('the_content', 'balanceTags', 50);
add_filter('get_the_excerpt', 'balanceTags', 9);
}
# Comments
# - Remove WordPress paragraph generator.
# - Remove WordPress auto-link generator.
# - Scramble important tags before passing them to the kses filter.
# - Run Markdown on excerpt then remove paragraph tags.
if (MARKDOWN_WP_COMMENTS) {
remove_filter('comment_text', 'wpautop', 30);
remove_filter('comment_text', 'make_clickable');
add_filter('pre_comment_content', 'Markdown', 6);
add_filter('pre_comment_content', 'mdwp_hide_tags', 8);
add_filter('pre_comment_content', 'mdwp_show_tags', 12);
add_filter('get_comment_text', 'Markdown', 6);
add_filter('get_comment_excerpt', 'Markdown', 6);
add_filter('get_comment_excerpt', 'mdwp_strip_p', 7);
global $mdwp_hidden_tags, $mdwp_placeholders;
$mdwp_hidden_tags = explode(' ',
'
", $text);
}
return $text;
}
function mdwp_strip_p($t) { return preg_replace('{?p>}i', '', $t); }
function mdwp_hide_tags($text) {
global $mdwp_hidden_tags, $mdwp_placeholders;
return str_replace($mdwp_hidden_tags, $mdwp_placeholders, $text);
}
function mdwp_show_tags($text) {
global $mdwp_hidden_tags, $mdwp_placeholders;
return str_replace($mdwp_placeholders, $mdwp_hidden_tags, $text);
}
}
### bBlog Plugin Info ###
function identify_modifier_markdown() {
return array(
'name' => 'markdown',
'type' => 'modifier',
'nicename' => 'Markdown',
'description' => 'A text-to-HTML conversion tool for web writers',
'authors' => 'Michel Fortin and John Gruber',
'licence' => 'BSD-like',
'version' => MARKDOWN_VERSION,
'help' => 'Markdown syntax allows you to write using an easy-to-read, easy-to-write plain text format. Based on the original Perl version by John Gruber. More...'
);
}
### Smarty Modifier Interface ###
function smarty_modifier_markdown($text) {
return Markdown($text);
}
### Textile Compatibility Mode ###
# Rename this file to "classTextile.php" and it can replace Textile everywhere.
if (strcasecmp(substr(__FILE__, -16), "classTextile.php") == 0) {
# Try to include PHP SmartyPants. Should be in the same directory.
@include_once 'smartypants.php';
# Fake Textile class. It calls Markdown instead.
class Textile {
function TextileThis($text, $lite='', $encode='') {
if ($lite == '' && $encode == '') $text = Markdown($text);
if (function_exists('SmartyPants')) $text = SmartyPants($text);
return $text;
}
# Fake restricted version: restrictions are not supported for now.
function TextileRestricted($text, $lite='', $noimage='') {
return $this->TextileThis($text, $lite);
}
# Workaround to ensure compatibility with TextPattern 4.0.3.
function blockLite($text) { return $text; }
}
}
#
# Markdown Parser Class
#
class Markdown_Parser {
### Configuration Variables ###
# Change to ">" for HTML output.
var $empty_element_suffix = MARKDOWN_EMPTY_ELEMENT_SUFFIX;
var $tab_width = MARKDOWN_TAB_WIDTH;
# Change to `true` to disallow markup or entities.
var $no_markup = false;
var $no_entities = false;
# Predefined urls and titles for reference links and images.
var $predef_urls = array();
var $predef_titles = array();
### Parser Implementation ###
# Regex to match balanced [brackets].
# Needed to insert a maximum bracked depth while converting to PHP.
var $nested_brackets_depth = 6;
var $nested_brackets_re;
var $nested_url_parenthesis_depth = 4;
var $nested_url_parenthesis_re;
# Table of hash values for escaped characters:
var $escape_chars = '\`*_{}[]()>#+-.!';
var $escape_chars_re;
function Markdown_Parser() {
#
# Constructor function. Initialize appropriate member variables.
#
$this->_initDetab();
$this->prepareItalicsAndBold();
$this->nested_brackets_re =
str_repeat('(?>[^\[\]]+|\[', $this->nested_brackets_depth).
str_repeat('\])*', $this->nested_brackets_depth);
$this->nested_url_parenthesis_re =
str_repeat('(?>[^()\s]+|\(', $this->nested_url_parenthesis_depth).
str_repeat('(?>\)))*', $this->nested_url_parenthesis_depth);
$this->escape_chars_re = '['.preg_quote($this->escape_chars).']';
# Sort document, block, and span gamut in ascendent priority order.
asort($this->document_gamut);
asort($this->block_gamut);
asort($this->span_gamut);
}
# Internal hashes used during transformation.
var $urls = array();
var $titles = array();
var $html_hashes = array();
# Status flag to avoid invalid nesting.
var $in_anchor = false;
function setup() {
#
# Called before the transformation process starts to setup parser
# states.
#
# Clear global hashes.
$this->urls = $this->predef_urls;
$this->titles = $this->predef_titles;
$this->html_hashes = array();
$in_anchor = false;
}
function teardown() {
#
# Called after the transformation process to clear any variable
# which may be taking up memory unnecessarly.
#
$this->urls = array();
$this->titles = array();
$this->html_hashes = array();
}
function transform($text) {
#
# Main function. Performs some preprocessing on the input text
# and pass it through the document gamut.
#
$this->setup();
# Remove UTF-8 BOM and marker character in input, if present.
$text = preg_replace('{^\xEF\xBB\xBF|\x1A}', '', $text);
# Standardize line endings:
# DOS to Unix and Mac to Unix
$text = preg_replace('{\r\n?}', "\n", $text);
# Make sure $text ends with a couple of newlines:
$text .= "\n\n";
# Convert all tabs to spaces.
$text = $this->detab($text);
# Turn block-level HTML blocks into hash entries
$text = $this->hashHTMLBlocks($text);
# Strip any lines consisting only of spaces and tabs.
# This makes subsequent regexen easier to write, because we can
# match consecutive blank lines with /\n+/ instead of something
# contorted like /[ ]*\n+/ .
$text = preg_replace('/^[ ]+$/m', '', $text);
# Run document gamut methods.
foreach ($this->document_gamut as $method => $priority) {
$text = $this->$method($text);
}
$this->teardown();
return $text . "\n";
}
var $document_gamut = array(
# Strip link definitions, store in hashes.
"stripLinkDefinitions" => 20,
"runBasicBlockGamut" => 30,
);
function stripLinkDefinitions($text) {
#
# Strips link definitions from text, stores the URLs and titles in
# hash references.
#
$less_than_tab = $this->tab_width - 1;
# Link defs are in the form: ^[id]: url "optional title"
$text = preg_replace_callback('{
^[ ]{0,'.$less_than_tab.'}\[(.+)\][ ]?: # id = $1
[ ]*
\n? # maybe *one* newline
[ ]*
(?:
<(.+?)> # url = $2
|
(\S+?) # url = $3
)
[ ]*
\n? # maybe one newline
[ ]*
(?:
(?<=\s) # lookbehind for whitespace
["(]
(.*?) # title = $4
[")]
[ ]*
)? # title is optional
(?:\n+|\Z)
}xm',
array(&$this, '_stripLinkDefinitions_callback'),
$text);
return $text;
}
function _stripLinkDefinitions_callback($matches) {
$link_id = strtolower($matches[1]);
$url = $matches[2] == '' ? $matches[3] : $matches[2];
$this->urls[$link_id] = $url;
$this->titles[$link_id] =& $matches[4];
return ''; # String that will replace the block
}
function hashHTMLBlocks($text) {
if ($this->no_markup) return $text;
$less_than_tab = $this->tab_width - 1;
# Hashify HTML blocks:
# We only want to do this for block-level HTML tags, such as headers,
# lists, and tables. That's because we still want to wrap
s around
# "paragraphs" that are wrapped in non-block-level tags, such as anchors,
# phrase emphasis, and spans. The list of tags we're looking for is
# hard-coded:
#
# * List "a" is made of tags which can be both inline or block-level.
# These will be treated block-level when the start tag is alone on
# its line, otherwise they're not matched here and will be taken as
# inline later.
# * List "b" is made of tags which are always block-level;
#
$block_tags_a_re = 'ins|del';
$block_tags_b_re = 'p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|'.
'script|noscript|form|fieldset|iframe|math|svg|'.
'article|section|nav|aside|hgroup|header|footer|'.
'figure';
# Regular expression for the content of a block tag.
$nested_tags_level = 4;
$attr = '
(?> # optional tag attributes
\s # starts with whitespace
(?>
[^>"/]+ # text outside quotes
|
/+(?!>) # slash not followed by ">"
|
"[^"]*" # text inside double quotes (tolerate ">")
|
\'[^\']*\' # text inside single quotes (tolerate ">")
)*
)?
';
$content =
str_repeat('
(?>
[^<]+ # content without tag
|
<\2 # nested opening tag
'.$attr.' # attributes
(?>
/>
|
>', $nested_tags_level). # end of opening tag
'.*?'. # last level nested tag content
str_repeat('
\2\s*> # closing nested tag
)
|
<(?!/\2\s*> # other tags with a different name
)
)*',
$nested_tags_level);
$content2 = str_replace('\2', '\3', $content);
# First, look for nested blocks, e.g.:
#
#
# tags for inner block must be indented.
#
#
#
# The outermost tags must start at the left margin for this to match, and
# the inner nested divs must be indented.
# We need to do this before the next, more liberal match, because the next
# match will start at the first `
` and stop at the first `
`.
$text = preg_replace_callback('{(?>
(?>
(?<=\n\n) # Starting after a blank line
| # or
\A\n? # the beginning of the doc
)
( # save in $1
# Match from `\n` to `\n`, handling nested tags
# in between.
[ ]{0,'.$less_than_tab.'}
<('.$block_tags_b_re.')# start tag = $2
'.$attr.'> # attributes followed by > and \n
'.$content.' # content, support nesting
\2> # the matching end tag
[ ]* # trailing spaces/tabs
(?=\n+|\Z) # followed by a newline or end of document
| # Special version for tags of group a.
[ ]{0,'.$less_than_tab.'}
<('.$block_tags_a_re.')# start tag = $3
'.$attr.'>[ ]*\n # attributes followed by >
'.$content2.' # content, support nesting
\3> # the matching end tag
[ ]* # trailing spaces/tabs
(?=\n+|\Z) # followed by a newline or end of document
| # Special case just for . It was easier to make a special
# case than to make the other regex more complicated.
[ ]{0,'.$less_than_tab.'}
<(hr) # start tag = $2
'.$attr.' # attributes
/?> # the matching end tag
[ ]*
(?=\n{2,}|\Z) # followed by a blank line or end of document
| # Special case for standalone HTML comments:
[ ]{0,'.$less_than_tab.'}
(?s:
)
[ ]*
(?=\n{2,}|\Z) # followed by a blank line or end of document
| # PHP and ASP-style processor instructions ( and <%)
[ ]{0,'.$less_than_tab.'}
(?s:
<([?%]) # $2
.*?
\2>
)
[ ]*
(?=\n{2,}|\Z) # followed by a blank line or end of document
)
)}Sxmi',
array(&$this, '_hashHTMLBlocks_callback'),
$text);
return $text;
}
function _hashHTMLBlocks_callback($matches) {
$text = $matches[1];
$key = $this->hashBlock($text);
return "\n\n$key\n\n";
}
function hashPart($text, $boundary = 'X') {
#
# Called whenever a tag must be hashed when a function insert an atomic
# element in the text stream. Passing $text to through this function gives
# a unique text-token which will be reverted back when calling unhash.
#
# The $boundary argument specify what character should be used to surround
# the token. By convension, "B" is used for block elements that needs not
# to be wrapped into paragraph tags at the end, ":" is used for elements
# that are word separators and "X" is used in the general case.
#
# Swap back any tag hash found in $text so we do not have to `unhash`
# multiple times at the end.
$text = $this->unhash($text);
# Then hash the block.
static $i = 0;
$key = "$boundary\x1A" . ++$i . $boundary;
$this->html_hashes[$key] = $text;
return $key; # String that will replace the tag.
}
function hashBlock($text) {
#
# Shortcut function for hashPart with block-level boundaries.
#
return $this->hashPart($text, 'B');
}
var $block_gamut = array(
#
# These are all the transformations that form block-level
# tags like paragraphs, headers, and list items.
#
"doHeaders" => 10,
"doHorizontalRules" => 20,
"doLists" => 40,
"doCodeBlocks" => 50,
"doBlockQuotes" => 60,
);
function runBlockGamut($text) {
#
# Run block gamut tranformations.
#
# We need to escape raw HTML in Markdown source before doing anything
# else. This need to be done for each block, and not only at the
# begining in the Markdown function since hashed blocks can be part of
# list items and could have been indented. Indented blocks would have
# been seen as a code block in a previous pass of hashHTMLBlocks.
$text = $this->hashHTMLBlocks($text);
return $this->runBasicBlockGamut($text);
}
function runBasicBlockGamut($text) {
#
# Run block gamut tranformations, without hashing HTML blocks. This is
# useful when HTML blocks are known to be already hashed, like in the first
# whole-document pass.
#
foreach ($this->block_gamut as $method => $priority) {
$text = $this->$method($text);
}
# Finally form paragraph and restore hashed blocks.
$text = $this->formParagraphs($text);
return $text;
}
function doHorizontalRules($text) {
# Do Horizontal Rules:
return preg_replace(
'{
^[ ]{0,3} # Leading space
([-*_]) # $1: First marker
(?> # Repeated marker group
[ ]{0,2} # Zero, one, or two spaces.
\1 # Marker character
){2,} # Group repeated at least twice
[ ]* # Tailing spaces
$ # End of line.
}mx',
"\n".$this->hashBlock("empty_element_suffix")."\n",
$text);
}
var $span_gamut = array(
#
# These are all the transformations that occur *within* block-level
# tags like paragraphs, headers, and list items.
#
# Process character escapes, code spans, and inline HTML
# in one shot.
"parseSpan" => -30,
# Process anchor and image tags. Images must come first,
# because ![foo][f] looks like an anchor.
"doImages" => 10,
"doAnchors" => 20,
# Make links out of things like ``
# Must come after doAnchors, because you can use < and >
# delimiters in inline links like [this]().
"doAutoLinks" => 30,
"encodeAmpsAndAngles" => 40,
"doItalicsAndBold" => 50,
"doHardBreaks" => 60,
);
function runSpanGamut($text) {
#
# Run span gamut tranformations.
#
foreach ($this->span_gamut as $method => $priority) {
$text = $this->$method($text);
}
return $text;
}
function doHardBreaks($text) {
# Do hard breaks:
return preg_replace_callback('/ {2,}\n/',
array(&$this, '_doHardBreaks_callback'), $text);
}
function _doHardBreaks_callback($matches) {
return $this->hashPart(" empty_element_suffix\n");
}
function doAnchors($text) {
#
# Turn Markdown link shortcuts into XHTML tags.
#
if ($this->in_anchor) return $text;
$this->in_anchor = true;
#
# First, handle reference-style links: [link text] [id]
#
$text = preg_replace_callback('{
( # wrap whole match in $1
\[
('.$this->nested_brackets_re.') # link text = $2
\]
[ ]? # one optional space
(?:\n[ ]*)? # one optional newline followed by spaces
\[
(.*?) # id = $3
\]
)
}xs',
array(&$this, '_doAnchors_reference_callback'), $text);
#
# Next, inline-style links: [link text](url "optional title")
#
$text = preg_replace_callback('{
( # wrap whole match in $1
\[
('.$this->nested_brackets_re.') # link text = $2
\]
\( # literal paren
[ \n]*
(?:
<(.+?)> # href = $3
|
('.$this->nested_url_parenthesis_re.') # href = $4
)
[ \n]*
( # $5
([\'"]) # quote char = $6
(.*?) # Title = $7
\6 # matching quote
[ \n]* # ignore any spaces/tabs between closing quote and )
)? # title is optional
\)
)
}xs',
array(&$this, '_doAnchors_inline_callback'), $text);
#
# Last, handle reference-style shortcuts: [link text]
# These must come last in case you've also got [link text][1]
# or [link text](/foo)
#
$text = preg_replace_callback('{
( # wrap whole match in $1
\[
([^\[\]]+) # link text = $2; can\'t contain [ or ]
\]
)
}xs',
array(&$this, '_doAnchors_reference_callback'), $text);
$this->in_anchor = false;
return $text;
}
function _doAnchors_reference_callback($matches) {
$whole_match = $matches[1];
$link_text = $matches[2];
$link_id =& $matches[3];
if ($link_id == "") {
# for shortcut links like [this][] or [this].
$link_id = $link_text;
}
# lower-case and turn embedded newlines into spaces
$link_id = strtolower($link_id);
$link_id = preg_replace('{[ ]?\n}', ' ', $link_id);
if (isset($this->urls[$link_id])) {
$url = $this->urls[$link_id];
$url = $this->encodeAttribute($url);
$result = "titles[$link_id] ) ) {
$title = $this->titles[$link_id];
$title = $this->encodeAttribute($title);
$result .= " title=\"$title\"";
}
$link_text = $this->runSpanGamut($link_text);
$result .= ">$link_text";
$result = $this->hashPart($result);
}
else {
$result = $whole_match;
}
return $result;
}
function _doAnchors_inline_callback($matches) {
$whole_match = $matches[1];
$link_text = $this->runSpanGamut($matches[2]);
$url = $matches[3] == '' ? $matches[4] : $matches[3];
$title =& $matches[7];
$url = $this->encodeAttribute($url);
$result = "encodeAttribute($title);
$result .= " title=\"$title\"";
}
$link_text = $this->runSpanGamut($link_text);
$result .= ">$link_text";
return $this->hashPart($result);
}
function doImages($text) {
#
# Turn Markdown image shortcuts into tags.
#
#
# First, handle reference-style labeled images: ![alt text][id]
#
$text = preg_replace_callback('{
( # wrap whole match in $1
!\[
('.$this->nested_brackets_re.') # alt text = $2
\]
[ ]? # one optional space
(?:\n[ ]*)? # one optional newline followed by spaces
\[
(.*?) # id = $3
\]
)
}xs',
array(&$this, '_doImages_reference_callback'), $text);
#
# Next, handle inline images: 
# Don't forget: encode * and _
#
$text = preg_replace_callback('{
( # wrap whole match in $1
!\[
('.$this->nested_brackets_re.') # alt text = $2
\]
\s? # One optional whitespace character
\( # literal paren
[ \n]*
(?:
<(\S*)> # src url = $3
|
('.$this->nested_url_parenthesis_re.') # src url = $4
)
[ \n]*
( # $5
([\'"]) # quote char = $6
(.*?) # title = $7
\6 # matching quote
[ \n]*
)? # title is optional
\)
)
}xs',
array(&$this, '_doImages_inline_callback'), $text);
return $text;
}
function _doImages_reference_callback($matches) {
$whole_match = $matches[1];
$alt_text = $matches[2];
$link_id = strtolower($matches[3]);
if ($link_id == "") {
$link_id = strtolower($alt_text); # for shortcut links like ![this][].
}
$alt_text = $this->encodeAttribute($alt_text);
if (isset($this->urls[$link_id])) {
$url = $this->encodeAttribute($this->urls[$link_id]);
$result = "titles[$link_id])) {
$title = $this->titles[$link_id];
$title = $this->encodeAttribute($title);
$result .= " title=\"$title\"";
}
$result .= $this->empty_element_suffix;
$result = $this->hashPart($result);
}
else {
# If there's no such link ID, leave intact:
$result = $whole_match;
}
return $result;
}
function _doImages_inline_callback($matches) {
$whole_match = $matches[1];
$alt_text = $matches[2];
$url = $matches[3] == '' ? $matches[4] : $matches[3];
$title =& $matches[7];
$alt_text = $this->encodeAttribute($alt_text);
$url = $this->encodeAttribute($url);
$result = "encodeAttribute($title);
$result .= " title=\"$title\""; # $title already quoted
}
$result .= $this->empty_element_suffix;
return $this->hashPart($result);
}
function doHeaders($text) {
# Setext-style headers:
# Header 1
# ========
#
# Header 2
# --------
#
$text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx',
array(&$this, '_doHeaders_callback_setext'), $text);
# atx-style headers:
# # Header 1
# ## Header 2
# ## Header 2 with closing hashes ##
# ...
# ###### Header 6
#
$text = preg_replace_callback('{
^(\#{1,6}) # $1 = string of #\'s
[ ]*
(.+?) # $2 = Header text
[ ]*
\#* # optional closing #\'s (not counted)
\n+
}xm',
array(&$this, '_doHeaders_callback_atx'), $text);
return $text;
}
function _doHeaders_callback_setext($matches) {
# Terrible hack to check we haven't found an empty list item.
if ($matches[2] == '-' && preg_match('{^-(?: |$)}', $matches[1]))
return $matches[0];
$level = $matches[2]{0} == '=' ? 1 : 2;
$block = "".$this->runSpanGamut($matches[1])."";
return "\n" . $this->hashBlock($block) . "\n\n";
}
function _doHeaders_callback_atx($matches) {
$level = strlen($matches[1]);
$block = "".$this->runSpanGamut($matches[2])."";
return "\n" . $this->hashBlock($block) . "\n\n";
}
function doLists($text) {
#
# Form HTML ordered (numbered) and unordered (bulleted) lists.
#
$less_than_tab = $this->tab_width - 1;
# Re-usable patterns to match list item bullets and number markers:
$marker_ul_re = '[*+-]';
$marker_ol_re = '\d+[\.]';
$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
$markers_relist = array(
$marker_ul_re => $marker_ol_re,
$marker_ol_re => $marker_ul_re,
);
foreach ($markers_relist as $marker_re => $other_marker_re) {
# Re-usable pattern to match any entirel ul or ol list:
$whole_list_re = '
( # $1 = whole list
( # $2
([ ]{0,'.$less_than_tab.'}) # $3 = number of spaces
('.$marker_re.') # $4 = first list item marker
[ ]+
)
(?s:.+?)
( # $5
\z
|
\n{2,}
(?=\S)
(?! # Negative lookahead for another list item marker
[ ]*
'.$marker_re.'[ ]+
)
|
(?= # Lookahead for another kind of list
\n
\3 # Must have the same indentation
'.$other_marker_re.'[ ]+
)
)
)
'; // mx
# We use a different prefix before nested lists than top-level lists.
# See extended comment in _ProcessListItems().
if ($this->list_level) {
$text = preg_replace_callback('{
^
'.$whole_list_re.'
}mx',
array(&$this, '_doLists_callback'), $text);
}
else {
$text = preg_replace_callback('{
(?:(?<=\n)\n|\A\n?) # Must eat the newline
'.$whole_list_re.'
}mx',
array(&$this, '_doLists_callback'), $text);
}
}
return $text;
}
function _doLists_callback($matches) {
# Re-usable patterns to match list item bullets and number markers:
$marker_ul_re = '[*+-]';
$marker_ol_re = '\d+[\.]';
$marker_any_re = "(?:$marker_ul_re|$marker_ol_re)";
$list = $matches[1];
$list_type = preg_match("/$marker_ul_re/", $matches[4]) ? "ul" : "ol";
$marker_any_re = ( $list_type == "ul" ? $marker_ul_re : $marker_ol_re );
$list .= "\n";
$result = $this->processListItems($list, $marker_any_re);
$result = $this->hashBlock("<$list_type>\n" . $result . "$list_type>");
return "\n". $result ."\n\n";
}
var $list_level = 0;
function processListItems($list_str, $marker_any_re) {
#
# Process the contents of a single ordered or unordered list, splitting it
# into individual list items.
#
# The $this->list_level global keeps track of when we're inside a list.
# Each time we enter a list, we increment it; when we leave a list,
# we decrement. If it's zero, we're not in a list anymore.
#
# We do this because when we're not inside a list, we want to treat
# something like this:
#
# I recommend upgrading to version
# 8. Oops, now this line is treated
# as a sub-list.
#
# As a single paragraph, despite the fact that the second line starts
# with a digit-period-space sequence.
#
# Whereas when we're inside a list (or sub-list), that line will be
# treated as the start of a sub-list. What a kludge, huh? This is
# an aspect of Markdown's syntax that's hard to parse perfectly
# without resorting to mind-reading. Perhaps the solution is to
# change the syntax rules such that sub-lists must start with a
# starting cardinal number; e.g. "1." or "a.".
$this->list_level++;
# trim trailing blank lines:
$list_str = preg_replace("/\n{2,}\\z/", "\n", $list_str);
$list_str = preg_replace_callback('{
(\n)? # leading line = $1
(^[ ]*) # leading whitespace = $2
('.$marker_any_re.' # list marker and space = $3
(?:[ ]+|(?=\n)) # space only required if item is not empty
)
((?s:.*?)) # list item text = $4
(?:(\n+(?=\n))|\n) # tailing blank line = $5
(?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n))))
}xm',
array(&$this, '_processListItems_callback'), $list_str);
$this->list_level--;
return $list_str;
}
function _processListItems_callback($matches) {
$item = $matches[4];
$leading_line =& $matches[1];
$leading_space =& $matches[2];
$marker_space = $matches[3];
$tailing_blank_line =& $matches[5];
if ($leading_line || $tailing_blank_line ||
preg_match('/\n{2,}/', $item))
{
# Replace marker with the appropriate whitespace indentation
$item = $leading_space . str_repeat(' ', strlen($marker_space)) . $item;
$item = $this->runBlockGamut($this->outdent($item)."\n");
}
else {
# Recursion for sub-lists:
$item = $this->doLists($this->outdent($item));
$item = preg_replace('/\n+$/', '', $item);
$item = $this->runSpanGamut($item);
}
return "
" . $item . "
\n";
}
function doCodeBlocks($text) {
#
# Process Markdown `
` blocks.
#
$text = preg_replace_callback('{
(?:\n\n|\A\n?)
( # $1 = the code block -- one or more lines, starting with a space/tab
(?>
[ ]{'.$this->tab_width.'} # Lines must start with a tab or a tab-width of spaces
.*\n+
)+
)
((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc
}xm',
array(&$this, '_doCodeBlocks_callback'), $text);
return $text;
}
function _doCodeBlocks_callback($matches) {
$codeblock = $matches[1];
$codeblock = $this->outdent($codeblock);
$codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES);
# trim leading newlines and trailing newlines
$codeblock = preg_replace('/\A\n+|\n+\z/', '', $codeblock);
$codeblock = "
$codeblock\n
";
return "\n\n".$this->hashBlock($codeblock)."\n\n";
}
function makeCodeSpan($code) {
#
# Create a code span markup for $code. Called from handleSpanToken.
#
$code = htmlspecialchars(trim($code), ENT_NOQUOTES);
return $this->hashPart("$code");
}
var $em_relist = array(
'' => '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(? '(?:(? '(?<=\S|^)(? '(?<=\S|^)(?em_relist as $em => $em_re) {
foreach ($this->strong_relist as $strong => $strong_re) {
# Construct list of allowed token expressions.
$token_relist = array();
if (isset($this->em_strong_relist["$em$strong"])) {
$token_relist[] = $this->em_strong_relist["$em$strong"];
}
$token_relist[] = $em_re;
$token_relist[] = $strong_re;
# Construct master expression from list.
$token_re = '{('. implode('|', $token_relist) .')}';
$this->em_strong_prepared_relist["$em$strong"] = $token_re;
}
}
}
function doItalicsAndBold($text) {
$token_stack = array('');
$text_stack = array('');
$em = '';
$strong = '';
$tree_char_em = false;
while (1) {
#
# Get prepared regular expression for seraching emphasis tokens
# in current context.
#
$token_re = $this->em_strong_prepared_relist["$em$strong"];
#
# Each loop iteration search for the next emphasis token.
# Each token is then passed to handleSpanToken.
#
$parts = preg_split($token_re, $text, 2, PREG_SPLIT_DELIM_CAPTURE);
$text_stack[0] .= $parts[0];
$token =& $parts[1];
$text =& $parts[2];
if (empty($token)) {
# Reached end of text span: empty stack without emitting.
# any more emphasis.
while ($token_stack[0]) {
$text_stack[1] .= array_shift($token_stack);
$text_stack[0] .= array_shift($text_stack);
}
break;
}
$token_len = strlen($token);
if ($tree_char_em) {
# Reached closing marker while inside a three-char emphasis.
if ($token_len == 3) {
# Three-char closing marker, close em and strong.
array_shift($token_stack);
$span = array_shift($text_stack);
$span = $this->runSpanGamut($span);
$span = "$span";
$text_stack[0] .= $this->hashPart($span);
$em = '';
$strong = '';
} else {
# Other closing marker: close one em or strong and
# change current token state to match the other
$token_stack[0] = str_repeat($token{0}, 3-$token_len);
$tag = $token_len == 2 ? "strong" : "em";
$span = $text_stack[0];
$span = $this->runSpanGamut($span);
$span = "<$tag>$span$tag>";
$text_stack[0] = $this->hashPart($span);
$$tag = ''; # $$tag stands for $em or $strong
}
$tree_char_em = false;
} else if ($token_len == 3) {
if ($em) {
# Reached closing marker for both em and strong.
# Closing strong marker:
for ($i = 0; $i < 2; ++$i) {
$shifted_token = array_shift($token_stack);
$tag = strlen($shifted_token) == 2 ? "strong" : "em";
$span = array_shift($text_stack);
$span = $this->runSpanGamut($span);
$span = "<$tag>$span$tag>";
$text_stack[0] .= $this->hashPart($span);
$$tag = ''; # $$tag stands for $em or $strong
}
} else {
# Reached opening three-char emphasis marker. Push on token
# stack; will be handled by the special condition above.
$em = $token{0};
$strong = "$em$em";
array_unshift($token_stack, $token);
array_unshift($text_stack, '');
$tree_char_em = true;
}
} else if ($token_len == 2) {
if ($strong) {
# Unwind any dangling emphasis marker:
if (strlen($token_stack[0]) == 1) {
$text_stack[1] .= array_shift($token_stack);
$text_stack[0] .= array_shift($text_stack);
}
# Closing strong marker:
array_shift($token_stack);
$span = array_shift($text_stack);
$span = $this->runSpanGamut($span);
$span = "$span";
$text_stack[0] .= $this->hashPart($span);
$strong = '';
} else {
array_unshift($token_stack, $token);
array_unshift($text_stack, '');
$strong = $token;
}
} else {
# Here $token_len == 1
if ($em) {
if (strlen($token_stack[0]) == 1) {
# Closing emphasis marker:
array_shift($token_stack);
$span = array_shift($text_stack);
$span = $this->runSpanGamut($span);
$span = "$span";
$text_stack[0] .= $this->hashPart($span);
$em = '';
} else {
$text_stack[0] .= $token;
}
} else {
array_unshift($token_stack, $token);
array_unshift($text_stack, '');
$em = $token;
}
}
}
return $text_stack[0];
}
function doBlockQuotes($text) {
$text = preg_replace_callback('/
( # Wrap whole match in $1
(?>
^[ ]*>[ ]? # ">" at the start of a line
.+\n # rest of the first line
(.+\n)* # subsequent consecutive lines
\n* # blanks
)+
)
/xm',
array(&$this, '_doBlockQuotes_callback'), $text);
return $text;
}
function _doBlockQuotes_callback($matches) {
$bq = $matches[1];
# trim one level of quoting - trim whitespace-only lines
$bq = preg_replace('/^[ ]*>[ ]?|^[ ]+$/m', '', $bq);
$bq = $this->runBlockGamut($bq); # recurse
$bq = preg_replace('/^/m', " ", $bq);
# These leading spaces cause problem with
content,
# so we need to fix that:
$bq = preg_replace_callback('{(\s*
tags and unhashify HTML blocks
#
foreach ($grafs as $key => $value) {
if (!preg_match('/^B\x1A[0-9]+B$/', $value)) {
# Is a paragraph.
$value = $this->runSpanGamut($value);
$value = preg_replace('/^([ ]*)/', "
", $value);
$value .= "
";
$grafs[$key] = $this->unhash($value);
}
else {
# Is a block.
# Modify elements of @grafs in-place...
$graf = $value;
$block = $this->html_hashes[$graf];
$graf = $block;
// if (preg_match('{
// \A
// ( # $1 =
#
# Based by a filter by Matthew Wickline, posted to BBEdit-Talk.
# With some optimizations by Milian Wolff.
#
$addr = "mailto:" . $addr;
$chars = preg_split('/(? $char) {
$ord = ord($char);
# Ignore non-ascii chars.
if ($ord < 128) {
$r = ($seed * (1 + $key)) % 100; # Pseudo-random function.
# roughly 10% raw, 45% hex, 45% dec
# '@' *must* be encoded. I insist.
if ($r > 90 && $char != '@') /* do nothing */;
else if ($r < 45) $chars[$key] = ''.dechex($ord).';';
else $chars[$key] = ''.$ord.';';
}
}
$addr = implode('', $chars);
$text = implode('', array_slice($chars, 7)); # text without `mailto:`
$addr = "$text";
return $addr;
}
function parseSpan($str) {
#
# Take the string $str and parse it into tokens, hashing embeded HTML,
# escaped characters and handling code spans.
#
$output = '';
$span_re = '{
(
\\\\'.$this->escape_chars_re.'
|
(?no_markup ? '' : '
|
# comment
|
<\?.*?\?> | <%.*?%> # processing instruction
|
<[!$]?[-a-zA-Z0-9:_]+ # regular tags
(?>
\s
(?>[^"\'>]+|"[^"]*"|\'[^\']*\')*
)?
>
|
<[-a-zA-Z0-9:_]+\s*/> # xml-style empty tag
|
[-a-zA-Z0-9:_]+\s*> # closing tag
').'
)
}xs';
while (1) {
#
# Each loop iteration seach for either the next tag, the next
# openning code span marker, or the next escaped character.
# Each token is then passed to handleSpanToken.
#
$parts = preg_split($span_re, $str, 2, PREG_SPLIT_DELIM_CAPTURE);
# Create token from text preceding tag.
if ($parts[0] != "") {
$output .= $parts[0];
}
# Check if we reach the end.
if (isset($parts[1])) {
$output .= $this->handleSpanToken($parts[1], $parts[2]);
$str = $parts[2];
}
else {
break;
}
}
return $output;
}
function handleSpanToken($token, &$str) {
#
# Handle $token provided by parseSpan by determining its nature and
# returning the corresponding value that should replace it.
#
switch ($token{0}) {
case "\\":
return $this->hashPart("". ord($token{1}). ";");
case "`":
# Search for end marker in remaining text.
if (preg_match('/^(.*?[^`])'.preg_quote($token).'(?!`)(.*)$/sm',
$str, $matches))
{
$str = $matches[2];
$codespan = $this->makeCodeSpan($matches[1]);
return $this->hashPart($codespan);
}
return $token; // return as text since no ending marker found.
default:
return $this->hashPart($token);
}
}
function outdent($text) {
#
# Remove one level of line-leading tabs or spaces
#
return preg_replace('/^(\t|[ ]{1,'.$this->tab_width.'})/m', '', $text);
}
# String length function for detab. `_initDetab` will create a function to
# hanlde UTF-8 if the default function does not exist.
var $utf8_strlen = 'mb_strlen';
function detab($text) {
#
# Replace tabs with the appropriate amount of space.
#
# For each line we separate the line in blocks delemited by
# tab characters. Then we reconstruct every line by adding the
# appropriate number of space between each blocks.
$text = preg_replace_callback('/^.*\t.*$/m',
array(&$this, '_detab_callback'), $text);
return $text;
}
function _detab_callback($matches) {
$line = $matches[0];
$strlen = $this->utf8_strlen; # strlen function for UTF-8.
# Split in blocks.
$blocks = explode("\t", $line);
# Add each blocks to the line.
$line = $blocks[0];
unset($blocks[0]); # Do not add first block twice.
foreach ($blocks as $block) {
# Calculate amount of space, insert spaces, insert block.
$amount = $this->tab_width -
$strlen($line, 'UTF-8') % $this->tab_width;
$line .= str_repeat(" ", $amount) . $block;
}
return $line;
}
function _initDetab() {
#
# Check for the availability of the function in the `utf8_strlen` property
# (initially `mb_strlen`). If the function is not available, create a
# function that will loosely count the number of UTF-8 characters with a
# regular expression.
#
if (function_exists($this->utf8_strlen)) return;
$this->utf8_strlen = create_function('$text', 'return preg_match_all(
"/[\\\\x00-\\\\xBF]|[\\\\xC0-\\\\xFF][\\\\x80-\\\\xBF]*/",
$text, $m);');
}
function unhash($text) {
#
# Swap back in all the tags hashed by _HashHTMLBlocks.
#
return preg_replace_callback('/(.)\x1A[0-9]+\1/',
array(&$this, '_unhash_callback'), $text);
}
function _unhash_callback($matches) {
return $this->html_hashes[$matches[0]];
}
}
/*
PHP Markdown
============
Description
-----------
This is a PHP translation of the original Markdown formatter written in
Perl by John Gruber.
Markdown is a text-to-HTML filter; it translates an easy-to-read /
easy-to-write structured text format into HTML. Markdown's text format
is mostly similar to that of plain text email, and supports features such
as headers, *emphasis*, code blocks, blockquotes, and links.
Markdown's syntax is designed not as a generic markup language, but
specifically to serve as a front-end to (X)HTML. You can use span-level
HTML tags anywhere in a Markdown document, and you can use block level
HTML tags (like
and
as well).
For more information about Markdown's syntax, see:
Bugs
----
To file bug reports please send email to:
Please include with your report: (1) the example input; (2) the output you
expected; (3) the output Markdown actually produced.
Version History
---------------
See the readme file for detailed release notes for this version.
Copyright and License
---------------------
PHP Markdown
Copyright (c) 2004-2013 Michel Fortin
All rights reserved.
Based on Markdown
Copyright (c) 2003-2006 John Gruber
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name "Markdown" nor the names of its contributors may
be used to endorse or promote products derived from this software
without specific prior written permission.
This software is provided by the copyright holders and contributors "as
is" and any express or implied warranties, including, but not limited
to, the implied warranties of merchantability and fitness for a
particular purpose are disclaimed. In no event shall the copyright owner
or contributors be liable for any direct, indirect, incidental, special,
exemplary, or consequential damages (including, but not limited to,
procurement of substitute goods or services; loss of use, data, or
profits; or business interruption) however caused and on any theory of
liability, whether in contract, strict liability, or tort (including
negligence or otherwise) arising in any way out of the use of this
software, even if advised of the possibility of such damage.
*/
?>
================================================
FILE: extensions/modellist/ModellistModule.php
================================================
* @author Philipp Frischmuth
* @copyright Copyright (c) 2012, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
class ModellistModule extends OntoWiki_Module
{
public function init()
{
$this->view->headScript()->appendFile($this->view->moduleUrl . 'modellist.js');
$menuRegistry = OntoWiki_Menu_Registry::getInstance();
$menuRegistry->getMenu('application')->getSubMenu('View')->setEntry('Hide Knowledge Bases Box', '#');
$this->session = new Zend_Session_Namespace(_OWSESSION);
$this->allGraphUris = $this->_store->getAvailableModels(true);
$this->visibleGraphUris = $this->_store->getAvailableModels(false);
if (isset($this->session->showHiddenGraphs) && $this->session->showHiddenGraphs == true) {
$this->graphUris = $this->allGraphUris;
} else {
$this->graphUris = $this->visibleGraphUris;
}
}
public function shouldShow()
{
// show only if there are models (visible or hidden)
if (($this->allGraphUris) || ($this->_erfurt->getAc()->isActionAllowed('ModelManagement'))) {
return true;
}
return false;
}
/**
* Returns the menu of the module
*
* @return string
*/
public function getMenu()
{
if ($this->_erfurt->getAc()->isActionAllowed('ModelManagement')) {
$editMenu = new OntoWiki_Menu();
$editMenu->setEntry('Create Knowledge Base', $this->_config->urlBase . 'model/create');
}
$viewMenu = new OntoWiki_Menu();
$session = new Zend_Session_Namespace(_OWSESSION);
if (!isset($session->showHiddenGraphs) || $session->showHiddenGraphs == false) {
$viewMenu->setEntry('Show Hidden Knowledge Bases', array('class' => 'modellist_hidden_button show'));
} else {
$viewMenu->setEntry('Hide Hidden Knowledge Bases', array('class' => 'modellist_hidden_button'));
}
// build menu out of sub menus
$mainMenu = new OntoWiki_Menu();
if (isset($editMenu)) {
$mainMenu->setEntry('Edit', $editMenu);
}
$mainMenu->setEntry('View', $viewMenu);
return $mainMenu;
}
/**
* Returns the content for the model list.
*/
public function getContents()
{
$models = array();
$selectedModel = $this->_owApp->selectedModel ? $this->_owApp->selectedModel->getModelIri() : null;
$lang = $this->_config->languages->locale;
$titleHelper = new OntoWiki_Model_TitleHelper();
$titleHelper->addResources(array_keys($this->graphUris));
$useGraphUriAsLink = false;
if (isset($this->_privateConfig->useGraphUriAsLink) && (bool)$this->_privateConfig->useGraphUriAsLink) {
$useGraphUriAsLink = true;
}
foreach ($this->graphUris as $graphUri => $true) {
$linkUrl = $this->_config->urlBase . 'model/select/?m=' . urlencode($graphUri);
if ($useGraphUriAsLink) {
if (isset($this->_config->vhosts)) {
$vHostsArray = $this->_config->vhosts->toArray();
foreach ($vHostsArray as $vHostUri) {
if (strpos($graphUri, $vHostUri) !== false) {
// match
$linkUrl = $graphUri;
break;
}
}
}
}
$temp = array();
$temp['url'] = $linkUrl;
$temp['graphUri'] = $graphUri;
$temp['selected'] = ($selectedModel == $graphUri ? 'selected' : '');
// use URI if no title exists
$label = $titleHelper->getTitle($graphUri, $lang);
$temp['label'] = !empty($label) ? $label : $graphUri;
$temp['backendName'] = $true;
$models[] = $temp;
}
$content = $this->render('modellist', $models, 'models');
return $content;
}
public function getStateId()
{
$session = new Zend_Session_Namespace(_OWSESSION);
if (isset($session->showHiddenGraphs) && $session->showHiddenGraphs == true) {
$showHidden = 'true';
} else {
$showHidden = 'false';
}
$id = (string)$this->_owApp->getUser()->getUri()
. $this->_owApp->selectedModel
. $showHidden;
return $id;
}
public function getTitle()
{
return "Knowledge Bases";
}
}
================================================
FILE: extensions/modellist/default.ini
================================================
;;
; Static module configuration
;;
enabled = true
name = "Knowledge Bases Module"
description = "provides a model list with create and view menu."
author = "AKSW"
authorUrl = "http://aksw.org"
caching = yes
priority = 20
contexts[] = "main.sidewindows"
classes = "has-contextmenus-block"
[private]
; use graph URI iff vhost matches
;useGraphUriAsLink = true
================================================
FILE: extensions/modellist/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix : .
<> foaf:primaryTopic :modellist .
:modellist a doap:Project ;
doap:name "modellist" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Knowledge Bases Module" ;
doap:description "provides a model list with create and view menu." ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:class "has-contextmenus-block" ;
owconfig:hasModule :Default .
:Default a owconfig:Module ;
rdfs:label "Default" ;
owconfig:caching "true"^^xsd:boolean ;
owconfig:priority "20" ;
owconfig:context "main.sidewindows" .
:modellist doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/modellist/modellist.js
================================================
/**
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
$(document).ready(function() {
$('.modellist_hidden_button').livequery('click', function() {
if ($(this).hasClass('show')) {
sessionStore('showHiddenGraphs', true, {
method: 'set',
callback: function() {
updateModellistModule();
}
});
} else {
sessionStore('showHiddenGraphs', false, {
method: 'unset',
callback: function() {
updateModellistModule();
}
});
}
});
});
function updateModellistModule()
{
// Remove the context menu.
$('.contextmenu-enhanced .contextmenu').fadeOut(effectTime, function(){
$(this).remove();
})
var options = {
url: urlBase + 'module/get/name/modellist/id/modellist'
};
$.get(options.url, function(data) {
$('#modellist').replaceWith(data);
$('#modellist').addClass('has-contextmenus-block')
.addClass('windowbuttonscount-right-1')
.addClass('windowbuttonscount-left-1');
$('#modellist').enhanceWindow();
});
}
================================================
FILE: extensions/modellist/modellist.phtml
================================================
models)): ?>
models as $modelDetails): ?>
_('No knowledge bases found.') ?>
================================================
FILE: extensions/navigation/NavigationController.php
================================================
_store = $this->_owApp->erfurt->getStore();
$this->_translate = $this->_owApp->translate;
$this->_ac = $this->_erfurt->getAc();
$sessionKey = 'Navigation' . (isset($config->session->identifier) ? $config->session->identifier : '');
$this->stateSession = new Zend_Session_Namespace($sessionKey);
$this->_model = $this->_owApp->selectedModel;
if (isset($this->_request->m)) {
$this->_model = $_store->getModel($this->_request->m);
}
if (empty($this->_model)) {
throw new OntoWiki_Exception(
'Missing parameter m (model) and no selected model in session!'
);
}
// create title helper
$this->titleHelper = new OntoWiki_Model_TitleHelper($this->_model);
// Model Based Access Control
if (!$this->_ac->isModelAllowed('view', $this->_model->getModelIri())) {
throw new Erfurt_Ac_Exception('You are not allowed to read this model.');
}
}
/*
* The main action which is retrieved via ajax
*/
public function exploreAction()
{
// disable standart navigation
OntoWiki::getInstance()->getNavigation()->disableNavigation();
// translate navigation title to selected language
$this->view->placeholder('main.window.title')->set($this->_translate->_('Navigation'));
// check if setup is present
if (empty($this->_request->setup)) {
throw new OntoWiki_Exception('Missing parameter setup !');
}
// decode setup from JSON into array
$this->_setup = json_decode($this->_request->getParam('setup'));
// check if setup was not converted
if ($this->_setup == false) {
throw new OntoWiki_Exception(
'Invalid parameter setup (json_decode failed): ' . $this->_request->setup
);
}
// overwrite the hard limit with the given one
if (isset($this->_setup->state->limit)) {
$this->_limit = $this->_setup->state->limit;
}
// build initial view
$this->view->entries = $this->_queryNavigationEntries($this->_setup);
// trigger before output event
$this->startOutput($this->_setup);
// set view variable for the show more button
if ((count($this->view->entries) > $this->_limit) && $this->_setup->state->lastEvent != "search") {
// return only $_limit entries
$this->view->entries = array_slice($this->view->entries, 0, $this->_limit);
$this->view->showMeMore = true;
} else {
$this->view->showMeMore = false;
}
// if there's no entries, show text
if (empty($this->view->entries)) {
if (isset($this->_setup->state->searchString)) {
$this->_messages[] = array('type' => 'info', 'text' => 'No result for this search.');
} else {
$this->_messages[] = array('type' => 'info', 'text' => 'Nothing to navigate here.');
}
}
// the root entry (parent of the shown elements)
if (isset($this->_setup->state->parent)) {
$this->view->rootEntry = array();
$this->view->rootEntry['uri'] = $this->_setup->state->parent;
$this->view->rootEntry['url'] = $this->_getListLink($this->_setup->state->parent, $this->_setup);
$this->view->rootEntry['title'] = $this->_getTitle(
$this->_setup->state->parent,
isset($this->_setup->config->titleMode) ? $this->_setup->config->titleMode : null,
null
);
}
// if search string is set, show it in view
if (isset($this->_setup->state->searchString)) {
$this->view->searchString = $this->_setup->state->searchString;
}
// if rootName is set, show it in view
if (isset($this->_setup->config->rootName)) {
$this->view->rootName = $this->_setup->config->rootName;
}
// if rootURI is set, apply it to rootName in view
if (isset($this->_setup->config->rootURI)) {
$this->view->rootLink = $this->_getListLink(
$this->_setup->config->rootURI,
$this->_setup
);
}
// set view messages and setup
$this->view->messages = $this->_messages;
$this->view->setup = $this->_setup;
// trigger after end output
$this->endOutput($this->_setup);
// save state to session
$this->savestateServer($this->view, $this->_setup);
}
private function startOutput($config)
{
$event = new Erfurt_Event('onNavigationStartOutput');
$event->config = $config;
$event->trigger();
}
private function endOutput($config)
{
$event = new Erfurt_Event('onNavigationEndOutput');
$event->config = $config;
$event->trigger();
}
/*
* Saves current view, setup and model to state to use it on refresh
*/
protected function savestateServer($view, $setup)
{
// encode setup to json
$setup = json_encode($setup);
// replace \' and \" to ' and "
$replaceFrom = array("\\'", '\\"');
$replaceTo = array("'", '"');
$setup = str_replace($replaceFrom, $replaceTo, $setup);
// save view, setup and current model to state
$this->stateSession->view = $view->render("navigation/explore.phtml");
$this->stateSession->setup = $setup;
$this->stateSession->model = (string)$this->_model;
}
/*
* Queries all navigation entries according to a given setup
*/
protected function _queryNavigationEntries($setup)
{
if (isset($setup->config->cache)
&& $setup->config->cache == true
) {
$cache = $this->_owApp->erfurt->getCache(); // Object cache
$queryCache = $this->_owApp->erfurt->getQueryCache(); // query cache
}
// set cache id
$cid = 'nav_' . md5(serialize($setup) . $this->_model);
$this->_owApp->logger->info(
'NavigationController _queryNavigationEntries Input: ' . PHP_EOL . print_r($setup, true)
);
//*/
// try to load results from cache
if (isset($setup->config->cache)
&& $setup->config->cache == true
) {
if ($entriesCached = $cache->load($cid)) {
return $entriesCached;
}
// start transaction
$queryCache->startTransaction($cid);
}
// if user searched for something
if ($setup->state->lastEvent == "search") {
// search request
// @todo: also search request should not show ignored entities
$resVar = new Erfurt_Sparql_Query2_Var('resourceUri');
$typeVar = new Erfurt_Sparql_Query2_IriRef(EF_RDF_TYPE);
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar($resVar)->setDistinct(true);
$pattern = $this->_store->getSearchPattern(
$setup->state->searchString,
(string)$this->_model
);
$query->addElements($pattern);
$union = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
foreach ($setup->config->hierarchyTypes as $type) {
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
$groupPattern->addTriple(
$resVar,
$typeVar,
new Erfurt_Sparql_Query2_IriRef($type)
);
$union->addElement($groupPattern);
}
$query->addElement($union);
// set to _limit+1, so we can see if there are more than $_limit entries
$query->setLimit($this->_limit + 1);
} else {
// if there's no top query assigned and hideDefaultHierarchy is false
// generate query based on setup
if ((!isset($setup->config->hideDefaultHierarchy)
|| ($setup->config->hideDefaultHierarchy == false))
&& !isset($setup->config->query->top)
) {
$query = $this->_buildQuery($setup, false);
} elseif (isset($setup->config->query->top)) {
// if top query is assigned - use it
$query = Erfurt_Sparql_SimpleQuery::initWithString($setup->config->query->top);
} else {
$query = null;
}
}
// if there's something wrong with query generation - exit
if ($query == null) {
return;
}
// error logging
$this->_owApp->logger->info(
'NavigationController _queryNavigationEntries Query: ' . $query->__toString()
);
//*/
//
// get extended results
$allResults = $this->_model->sparqlQuery(
$query,
array('result_format' => 'extended')
);
// create res array
$results = array();
// parse to needed format
foreach ($allResults['results']['bindings'] as $res) {
if ($res['resourceUri']['type'] != 'bnode') {
$results[]['resourceUri'] = $res['resourceUri']['value'];
} else {
$results[]['resourceUri'] = $this->_getSubclass(
str_replace("_:", "", $res['resourceUri']['value']),
$setup
);
}
}
// if we need to show implicit elements
$showImplicit = false;
if (!isset($setup->config->rootElement)) {
if (!isset($setup->state->showImplicit)) {
if (isset($setup->config->showImplicitElements)
&& $setup->config->showImplicitElements == true
) {
$showImplicit = true;
}
} else {
if ($setup->state->showImplicit == true) {
$showImplicit = true;
}
}
}
// if we need to show implicit elements
// generate additional query for them
if ($showImplicit) {
// new query for regular event
if ($setup->state->lastEvent != "search") {
$query = $this->_buildQuery($setup, true);
$resultsImplicit = $this->_model->sparqlQuery(
$query,
array('result_format' => 'extended')
);
} else {
// new query for search
$query = $this->_buildStringSearchQuery($setup);
$resultsImplicit = $this->_model->sparqlQuery(
$query,
array('result_format' => 'extended')
);
}
// append implicit classes to results
foreach ($resultsImplicit['results']['bindings'] as $res) {
if (!in_array($res['resourceUri']['value'], $results)) {
if ($res['resourceUri']['type'] != 'bnode') {
$results[]['resourceUri'] = $res['resourceUri']['value'];
} else {
$results[]['resourceUri'] = $this->_getSubclass(
str_replace(
"_:",
"",
$res['resourceUri']['value']
),
$setup
);
}
}
}
}
// log results
$this->_owApp->logger->info(
'NavigationController _queryNavigationEntries Result: ' . PHP_EOL . print_r($allResults, true)
);
//*/
// set titleMode from config or set it to null if config is not assigned
if (isset($setup->config->titleMode)) {
$mode = $setup->config->titleMode;
} else {
$mode = null;
}
// if title mode set to titlehelper
// get titles of all resources
if ($mode == "titleHelper") {
if (isset($results)) {
foreach ($results as $result) {
$this->titleHelper->addResource($result['resourceUri']);
}
}
// add parent to titleHelper to get title
if (isset($setup->state->parent)) {
$this->titleHelper->addResource($setup->state->parent);
}
}
// create new array for navigation entries
$entries = array();
// if there's no query results - exit
if ($results == null) {
return;
}
// parse all results to entries
foreach ($results as $result) {
$entry = array();
// assing resource URI
$uri = $result['resourceUri'];
$entry = array();
$entry['title'] = $this->_getTitle($uri, $mode, $setup);
// get resource ling
$entry['link'] = $this->_getListLink($uri, $setup);
// chech if there's need to look for subresources
$checkSubs = false;
if (isset($setup->config->checkSub)
&& $setup->config->checkSub == true
) {
$checkSubs = true;
}
// if needed look for subresources
if ($checkSubs) {
// build sub query
$query = $this->_buildSubCheckQuery($uri, $setup);
// get results
$results = $this->_model->sparqlQuery($query);
// assigh count of results
$entry['sub'] = count($results);
} else {
// if there's no need to look for subres
// just set var to 1, so that "go deeper" arrow
// will be allways visible
$entry['sub'] = 1;
}
// check if filtering empty is enabled
$filterEmpty = false;
if (!isset($setup->state->showEmpty)) {
if (isset($setup->config->showEmptyElements)
&& $setup->config->showEmptyElements == false
) {
$filterEmpty = true;
}
} else {
if ($setup->state->showEmpty == false) {
$filterEmpty = true;
}
}
// do filter empty if needed
$show = true;
if ($filterEmpty) {
// generate query
$query = $this->_buildCountQuery($uri, $setup);
// get results
$results = $this->_model->sparqlQuery($query);
// depending on result format set count
if (isset($results[0]['callret-0'])) {
$count = $results[0]['callret-0'];
} else {
$count = count($results);
}
// if count is 0 do not show entry
if ($count == 0) {
$show = false;
}
}
if (isset($setup->config->checkUsage)
&& $setup->config->checkUsage == true
) {
// gen query
$query = $this->_buildUsageQuery($uri, $setup);
// get results
$results = $this->_model->sparqlQuery($query);
// depending on result format set count
if (isset($results[0]['callret-0'])) {
$count = $results[0]['callret-0'];
} else {
$count = count($results);
}
// if count is 0 do not show entry
if ($count == 0) {
$show = false;
}
}
// apply $show flag
if ($show) {
$entries[$uri] = $entry;
}
}
$this->_owApp->logger->info('ENTRIES: ' . print_r($entries, true));
if (isset($setup->config->cache) && $setup->config->cache == true) {
// save results to cache
$cache->save($entries, $cid);
// end cache transaction
$queryCache->endTransaction($cid);
}
return $entries;
}
protected function _getSubclass($node, $setup)
{
$subVar = new Erfurt_Sparql_Query2_Var('subResourceUri');
$searchVar = new Erfurt_Sparql_Query2_BlankNode($node);
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar($subVar);
$query->setDistinct();
$elements = array();
if (isset($setup->config->hierarchyRelations->in)) {
if (count($setup->config->hierarchyRelations->in) > 1) {
// init union var
$unionSub = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
// parse config gile
foreach ($setup->config->hierarchyRelations->in as $rel) {
// sub stuff
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$groupPattern->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$unionSub->addElement($groupPattern);
}
$elements[] = $unionSub;
} else {
$rel = $setup->config->hierarchyRelations->in;
// add optional sub relation
$elements[] = new Erfurt_Sparql_Query2_Triple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$searchVar
);
}
}
if (isset($setup->config->hierarchyRelations->out)) {
if (count($setup->config->hierarchyRelations->out) > 1) {
// init union var
$unionSub = new Erfurt_Sparql_Query2_GroupGraphPattern();
// parse config gile
foreach ($setup->config->hierarchyRelations->out as $rel) {
// sub stuff
$optionalPattern = new Erfurt_Sparql_Query2_OptionalGraphPattern();
// add triplen
$optionalPattern->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$unionSub->addElement($optionalPattern);
}
$elements[] = $unionSub;
} else {
$rel = $setup->config->hierarchyRelations->out;
// add optional sub relation
$elements[] = new Erfurt_Sparql_Query2_Triple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$subVar
);
}
}
$query->addElements($elements);
$result = $this->_model->sparqlQuery($query);
return $result[0]['subResourceUri'];
}
protected function _getTitle($uri, $mode, $setup)
{
$name = '';
// set default mode if none is set
if (!isset($mode) || $mode == null) {
$mode = "baseName";
}
// get title
if ($mode == "titleHelper") {
$name = $this->titleHelper->getTitle($uri, OntoWiki::getInstance()->language);
} elseif ($mode == "baseName") {
if (strrpos($uri, '#') > 0) {
$name = substr($uri, strrpos($uri, '#') + 1);
} elseif (strrpos($uri, '/') > 0) {
$name = substr($uri, strrpos($uri, '/') + 1);
} else {
$name = $uri;
}
} else {
$name = 'error';
}
// count entries
if (isset($setup->config->showCounts)
&& $setup->config->showCounts == true
) {
$query = $this->_buildCountQuery($uri, $setup);
$results = $this->_model->sparqlQuery($query);
if (isset($results[0]['callret-0'])) {
$count = $results[0]['callret-0'];
} else {
$count = count($results);
}
if ($count > 0) {
$name .= ' (' . $count . ')';
}
}
return $name;
}
/*
* Builds query for main actions (root, nav. deeper)
*/
protected function _buildQuery($setup, $forImplicit = false)
{
if (isset($setup->config->query->deeper)
&& isset($setup->state->parent)
) {
//$replace = ;
$queryString = str_replace(
"%resource%",
$setup->state->parent,
$setup->config->query->deeper
);
$query = Erfurt_Sparql_SimpleQuery::initWithString($queryString);
} else {
$query = new Erfurt_Sparql_Query2();
$query->addElements(
NavigationHelper::getSearchTriples(
$setup,
$forImplicit,
$this->_config->store->backend
)
);
$query->setDistinct(true);
$query->addProjectionVar(new Erfurt_Sparql_Query2_Var('resourceUri'));
}
// sorting
if (isset($setup->state->sorting)) {
$query->getOrder()->add(new Erfurt_Sparql_Query2_Var('sortRes'), "ASC");
} elseif (isset($setup->config->ordering->relation)) { // set ordering
$orderVar = new Erfurt_Sparql_Query2_Var('order');
$query->getWhere()->addElement(
new Erfurt_Sparql_Query2_OptionalGraphPattern(
array(
new Erfurt_Sparql_Query2_Triple(
new Erfurt_Sparql_Query2_Var('resourceUri'),
new Erfurt_Sparql_Query2_IriRef($setup->config->ordering->relation),
$orderVar
)
)
)
);
$query->getOrder()->add(
$orderVar,
$setup->config->ordering->modifier
);
}
// set offset
if (isset($setup->state->offset) && $setup->state->lastEvent == 'more') {
$query->setOffset($setup->state->offset);
$query->setLimit($this->_limit + 1);
} else {
$query->setLimit($this->_limit + 1);
}
return $query;
}
/*
* Builds search query string
*/
protected function _buildStringSearchQuery($setup)
{
// define vars
$searchVar = new Erfurt_Sparql_Query2_Var('resourceUri');
$subVar = new Erfurt_Sparql_Query2_Var('sub');
// define query
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar($searchVar);
$query->setDistinct();
// init union var
$union = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
// parse config
if (isset($setup->config->hierarchyRelations->out)) {
foreach ($setup->config->hierarchyRelations->out as $rel) {
// create new graph pattern
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$groupPattern->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$union->addElement($groupPattern);
}
}
// parse config
if (isset($setup->config->hierarchyRelations->in)) {
foreach ($setup->config->hierarchyRelations->in as $rel) {
// create new graph pattern
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$groupPattern->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($groupPattern);
}
}
// parse config
if (isset($setup->config->instanceRelation->out)) {
foreach ($setup->config->instanceRelation->out as $rel) {
// create new graph pattern
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$groupPattern->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($groupPattern);
}
}
// parse config
if (isset($setup->config->instanceRelation->in)) {
foreach ($setup->config->instanceRelation->in as $rel) {
// create new graph pattern
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$groupPattern->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$union->addElement($groupPattern);
}
}
$query->addElement($union);
// add regex filter for search string
$query->addFilter(
new Erfurt_Sparql_Query2_Regex(
new Erfurt_Sparql_Query2_Str($searchVar),
new Erfurt_Sparql_Query2_RDFLiteral($setup->state->searchString)
)
);
return $query;
}
/*
* Builds counting query for given $uri
*/
protected function _buildCountQuery($uri, $setup)
{
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar(new Erfurt_Sparql_Query2_Var('resourceUri'));
$query->setCountStar(true);
$query->setDistinct();
$query->addElements(NavigationHelper::getInstancesTriples($uri, $setup));
// error logging
$this->_owApp->logger->info(
'NavigationController: COUNTQUERY: ' . $query->__toString()
);
//*/
return $query;
}
/*
* Builds usage query for given $uri
*/
protected function _buildUsageQuery($uri, $setup)
{
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar(new Erfurt_Sparql_Query2_Var('resourceUri'));
$query->setCountStar(true);
$query->setDistinct();
return $query;
}
/*
* Builds query to check for subresources for $uri based on $setup
*/
protected function _buildSubCheckQuery($uri, $setup)
{
$subVar = new Erfurt_Sparql_Query2_Var('subResourceUri');
$searchVar = new Erfurt_Sparql_Query2_Var('resourceUri');
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar($subVar);
$query->setDistinct();
$this->_owApp->logger->info("data: " . print_r($query, true));
$elements = array();
$in = array();
$out = array();
if (isset($setup->config->hierarchyRelations->in)) {
if (count($setup->config->hierarchyRelations->in) > 1) {
// init union var
$unionSub = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
// parse config gile
foreach ($setup->config->hierarchyRelations->in as $rel) {
// sub stuff
$groupPattern = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$groupPattern->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$unionSub->addElement($groupPattern);
}
$in[] = $unionSub;
} else {
$rel = $setup->config->hierarchyRelations->in;
// add optional sub relation
// create optional graph to load sublacsses of selected class
$queryOptional = new Erfurt_Sparql_Query2_GroupGraphPattern();
$queryOptional->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$searchVar
);
$in[] = $queryOptional;
}
}
if (isset($setup->config->hierarchyRelations->out)) {
if (count($setup->config->hierarchyRelations->out) > 1) {
// init union var
$unionSub = new Erfurt_Sparql_Query2_GroupGraphPattern();
// parse config gile
foreach ($setup->config->hierarchyRelations->out as $rel) {
// sub stuff
$optPattern = new Erfurt_Sparql_Query2_OptionalGraphPattern();
// add triple
$optPattern->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$unionSub->addElement($optPattern);
}
$out[] = $unionSub;
} else {
$rel = $setup->config->hierarchyRelations->out;
// add optional sub relation
// create optional graph to load sublacsses of selected class
$queryOptional = new Erfurt_Sparql_Query2_GroupGraphPattern();
$queryOptional->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$subVar
);
$out[] = $queryOptional;
}
}
$inout = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
$inout->addElements($in);
$inout->addElements($out);
$elements[] = $inout;
// add filter
if ($this->_store->isInSyntaxSupported()) { // e.g. Virtuoso
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_InExpression($searchVar, array(new Erfurt_Sparql_Query2_IriRef($uri)))
);
} else { // sameTerm || sameTerm ... as supported by EfZendDb adapter
// add filter
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_Equals($searchVar, new Erfurt_Sparql_Query2_IriRef($uri))
);
}
// build
$query->addElements($elements);
$query->setLimit(1);
// log results
$this->_owApp->logger->info(
'NavigationController CHECK SUB: ' . PHP_EOL . $query->__toString()
);
return $query;
}
/*
* This method returns the link to the resource list action
* according to a given URI in the navigation module and a
* given navigation setup
*/
protected function _getListLink($uri, $setup)
{
if (isset($setup->config->directLink) && $setup->config->directLink) {
$return = new OntoWiki_Url(array('route' => 'properties'), array('r'));
// set URL
$return->setParam('r', $uri, true);
return $return;
}
$owUrl = new OntoWiki_Url(
array('route' => 'instances'),
array()
);
$return = (string)$owUrl;
// at the moment, we use r= here, not class=
$return .= "?init";
$conf = array();
// there is a shortcut for rdfs classes
if (isset($setup->config->list->config)) {
$configString = str_replace("|", '"', $setup->config->list->config);
$configString = str_replace("%resource%", $uri, $configString);
$conf = json_decode($configString);
} else {
if (isset($setup->config->list->query)) {
// show properties
if (isset($setup->config->list->shownProperties)) {
$configString = str_replace("|", '"', $setup->config->list->shownProperties);
$configString = str_replace("%resource%", $uri, $configString);
$conf['shownProperties'][] = json_decode($configString);
}
// query
$configQuery = str_replace("%resource%", $uri, $setup->config->list->query);
$configQuery = str_replace("\n", " ", $configQuery);
$conf['filter'][] = array(
'mode' => 'query',
'query' => $configQuery
);
} else {
if (isset($setup->config->instanceRelation->out)
&& isset($setup->config->instanceRelation->in)
&& ($setup->config->instanceRelation->out[0] == EF_RDF_TYPE)
&& ($setup->config->hierarchyRelations->in[0] == EF_RDFS_SUBCLASSOF)
) {
$conf['filter'][] = array(
'mode' => 'rdfsclass',
'rdfsclass' => $uri,
'action' => 'add'
);
} else {
$conf['filter'][] = array(
'mode' => 'cnav',
'cnav' => $setup,
'uri' => $uri,
'action' => 'add'
);
}
}
}
return $return . "&instancesconfig=" . urlencode(json_encode($conf));
}
}
================================================
FILE: extensions/navigation/NavigationHelper.php
================================================
config->hierarchyRelations->out)) {
foreach ($setup->config->hierarchyRelations->out as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$classVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
// parse config
if (isset($setup->config->hierarchyRelations->in)) {
foreach ($setup->config->hierarchyRelations->in as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$classVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
// parse config
if (isset($setup->config->instanceRelation->in)) {
foreach ($setup->config->instanceRelation->in as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$classVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
// parse config
if (isset($setup->config->instanceRelation->out)) {
foreach ($setup->config->instanceRelation->out as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$classVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
$elements[] = $union;
$owApp = OntoWiki::getInstance();
$modelIRI = (string)$owApp->selectedModel;
$store = $owApp->erfurt->getStore();
// get all subclass of the super class
$classes = array();
if (isset($setup->config->hierarchyRelations->out)) {
foreach ($setup->config->hierarchyRelations->out as $rel) {
$classes += $store->getTransitiveClosure($modelIRI, $rel, $uri, false);
}
}
if (isset($setup->config->hierarchyRelations->in)) {
foreach ($setup->config->hierarchyRelations->in as $rel) {
$classes += $store->getTransitiveClosure($modelIRI, $rel, $uri, true);
}
}
// create filter for types
$filterType = array();
$filterUris = array();
$counted = array();
foreach ($classes as $class) {
// get uri
$uri = ($class['parent'] != '') ? $class['parent'] : $class['node'];
// if this class is already counted - continue
if (in_array($uri, $counted)) {
if ($class['node'] != '') {
$uri = $class['node'];
if (in_array($uri, $counted)) {
continue;
}
} else {
continue;
}
}
$uriElem = new Erfurt_Sparql_Query2_IriRef($uri);
$filterUris[] = $uriElem;
$filterType[] = new Erfurt_Sparql_Query2_Equals($classVar, $uriElem);
// add uri to counted
$counted[] = $uri;
}
if ($store->isInSyntaxSupported()) { // e.g. Virtuoso
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_InExpression($classVar, $filterUris)
);
} else { // sameTerm || sameTerm ... as supported by EfZendDb adapter
// add filter
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_ConditionalOrExpression($filterType)
);
}
return $elements;
}
public static function getSearchTriples($setup, $forImplicit = false, $backend = 'zenddb')
{
$searchVar = new Erfurt_Sparql_Query2_Var('resourceUri');
$classVar = new Erfurt_Sparql_Query2_Var('classUri');
$subVar = new Erfurt_Sparql_Query2_Var('subResourceUri');
$elements = array();
// if deeper query
if (isset($setup->state->parent)) {
$mainUnion = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
// in relations
if (isset($setup->config->hierarchyRelations->in)) {
// default stuff
if (count($setup->config->hierarchyRelations->in) > 1) {
// parse config gile
foreach ($setup->config->hierarchyRelations->in as $rel) {
// set type
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
new Erfurt_Sparql_Query2_IriRef($setup->state->parent)
);
// add triplet to union var
$mainUnion->addElement($ggp);
}
} else {
$rel = $setup->config->hierarchyRelations->in;
$queryOptional = new Erfurt_Sparql_Query2_GroupGraphPattern();
$queryOptional->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
new Erfurt_Sparql_Query2_IriRef($setup->state->parent)
);
$mainUnion->addElement($queryOptional);
}
}
// out relations
if (isset($setup->config->hierarchyRelations->out)) {
// if there's out relations
if (count($setup->config->hierarchyRelations->out) > 1) {
// parse config gile
foreach ($setup->config->hierarchyRelations->out as $rel) {
// set type
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
new Erfurt_Sparql_Query2_IriRef($setup->state->parent),
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$mainUnion->addElement($ggp);
}
} else {
// get one relation
$rel = $setup->config->hierarchyRelations->out;
$queryOptional = new Erfurt_Sparql_Query2_GroupGraphPattern();
$queryOptional->addTriple(
new Erfurt_Sparql_Query2_IriRef($setup->state->parent),
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$searchVar
);
$mainUnion->addElement($queryOptional);
}
}
$elements[] = $mainUnion;
} else { // if default request
if (!$forImplicit) {
$elements[] = new Erfurt_Sparql_Query2_Triple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef(EF_RDF_TYPE),
$classVar
);
// request sub elements
// in relations
$optional = new Erfurt_Sparql_Query2_OptionalGraphPattern();
$unionSub = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
if (isset($setup->config->hierarchyRelations->in)) {
if (count($setup->config->hierarchyRelations->in) > 1) {
// parse config gile
foreach ($setup->config->hierarchyRelations->in as $rel) {
// sub stuff
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$unionSub->addElement($ggp);
}
} else {
$rel = $setup->config->hierarchyRelations->in;
// add optional sub relation
// create optional graph to load sublacsses of selected class
$optional->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$searchVar
);
}
}
if (isset($setup->config->hierarchyRelations->out)) {
// init union var
if (count($setup->config->hierarchyRelations->out) > 1) {
// parse config gile
foreach ($setup->config->hierarchyRelations->out as $rel) {
// sub stuff
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$unionSub->addElement($ggp);
}
} else {
$rel = $setup->config->hierarchyRelations->out;
// add optional sub relation
// create optional graph to load sublacsses of selected class
$optional->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$subVar
);
}
}
if ($unionSub->size() > 0) {
$optional->addElement($unionSub);
}
$elements[] = $optional;
// create filter for types
$filterType = array();
$filterUris = array();
foreach ($setup->config->hierarchyTypes as $type) {
$uriElem = new Erfurt_Sparql_Query2_IriRef($type);
$filterUris[] = $uriElem;
$filterType[] = new Erfurt_Sparql_Query2_Equals($classVar, $uriElem);
}
$owApp = OntoWiki::getInstance();
$store = $owApp->erfurt->getStore();
if ($store->isInSyntaxSupported()) { // e.g. Virtuoso
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_InExpression($classVar, $filterUris)
);
} else { // sameTerm || sameTerm ... as supported by EfZendDb adapter
// add filter
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_ConditionalOrExpression($filterType)
);
}
} else {
// define subvar
$subVar = new Erfurt_Sparql_Query2_Var('sub');
// init union var
$union = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
// parse config
if (isset($setup->config->hierarchyRelations->out)) {
if (is_string($setup->config->hierarchyRelations->out)) {
$setup->config->hierarchyRelations->out = array($setup->config->hierarchyRelations->out);
}
foreach ($setup->config->hierarchyRelations->out as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
// parse config
if (isset($setup->config->hierarchyRelations->in)) {
if (is_string($setup->config->hierarchyRelations->in)) {
$setup->config->hierarchyRelations->in = array($setup->config->hierarchyRelations->in);
}
foreach ($setup->config->hierarchyRelations->in as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
// parse config
if (isset($setup->config->instanceRelation->out)) {
if (is_string($setup->config->instanceRelation->out)) {
$setup->config->instanceRelation->out = array($setup->config->instanceRelation->out);
}
foreach ($setup->config->instanceRelation->out as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$subVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
// parse config
if (isset($setup->config->instanceRelation->in)) {
if (is_string($setup->config->instanceRelation->in)) {
$setup->config->instanceRelation->in = array($setup->config->instanceRelation->in);
}
foreach ($setup->config->instanceRelation->in as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
$subVar
);
// add triplet to union var
$union->addElement($ggp);
}
}
$elements[] = $union;
}
}
if (isset($setup->config->rootElement)) {
$union = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
if (isset($setup->config->hierarchyRelations->in)) {
foreach ($setup->config->hierarchyRelations->in as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
new Erfurt_Sparql_Query2_IriRef($setup->config->rootElement)
);
// add triplet to union var
$union->addElement($ggp);
}
$superUsed = true;
}
if (isset($setup->config->hierarchyRelations->out)) {
foreach ($setup->config->hierarchyRelations->out as $rel) {
// create new graph pattern
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
// add triplen
$ggp->addTriple(
new Erfurt_Sparql_Query2_IriRef($setup->config->rootElement),
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
// add triplet to union var
$union->addElement($ggp);
}
$superUsed = true;
}
if ($superUsed) {
$elements[] = $union;
}
}
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_isBlank(
new Erfurt_Sparql_Query2_Var('resourceUri')
)
)
);
// namespaces to be ignored, rdfs/owl-defined objects
if (!isset($setup->state->showHidden)) {
if (isset($setup->config->hiddenRelation)) {
// optional var
$queryOptional = new Erfurt_Sparql_Query2_OptionalGraphPattern();
// parse config
if (is_string($setup->config->hiddenRelation)) {
$setup->config->hiddenRelation = array($setup->config->hiddenRelation);
}
foreach ($setup->config->hiddenRelation as $ignore) {
$queryOptional->addTriple(
new Erfurt_Sparql_Query2_Var('resourceUri'),
new Erfurt_Sparql_Query2_IriRef($ignore),
new Erfurt_Sparql_Query2_Var('reg')
);
$regUsed = true;
}
if ($regUsed) {
$elements[] = $queryOptional;
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_bound(
new Erfurt_Sparql_Query2_Var('reg')
)
)
);
}
}
if (isset($setup->config->hiddenNS)) {
// parse config
foreach ($setup->config->hiddenNS as $ignore) {
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_Regex(
new Erfurt_Sparql_Query2_Str(new Erfurt_Sparql_Query2_Var('resourceUri')),
new Erfurt_Sparql_Query2_RDFLiteral('^' . $ignore)
)
)
);
}
}
}
// dont't show rdfs/owl entities and subtypes in the first level
if (!isset($setup->state->parent) && !isset($setup->config->rootElement)) {
OntoWiki::getInstance()->logger->info("BACKEND: " . $backend);
// optional var
if ($backend == "zenddb") {
$queryUnion = new Erfurt_Sparql_Query2_OptionalGraphPattern();
} else {
$queryUnion = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
}
if (isset($setup->config->hierarchyRelations->in)) {
if (count($setup->config->hierarchyRelations->in) > 1) {
foreach ($setup->config->hierarchyRelations->in as $rel) {
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel),
new Erfurt_Sparql_Query2_Var('super')
);
$queryUnion->addElement($ggp);
}
} else {
$rel = $setup->config->hierarchyRelations->in;
// add optional sub relation
if ($backend == "zenddb") {
$queryUnion->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
new Erfurt_Sparql_Query2_Var('super')
);
} else {
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
$ggp->addTriple(
$searchVar,
new Erfurt_Sparql_Query2_IriRef($rel[0]),
new Erfurt_Sparql_Query2_Var('super')
);
$queryUnion->addElement($ggp);
}
}
$superUsed = true;
}
if (isset($setup->config->hierarchyRelations->out)) {
if (count($setup->config->hierarchyRelations->out) > 1) {
foreach ($setup->config->hierarchyRelations->out as $rel) {
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
$ggp->addTriple(
new Erfurt_Sparql_Query2_Var('super'),
new Erfurt_Sparql_Query2_IriRef($rel),
$searchVar
);
$queryUnion->addElement($ggp);
}
} else {
$rel = $setup->config->hierarchyRelations->out;
// add optional sub relation
if ($backend == "zenddb") {
$queryUnion->addTriple(
new Erfurt_Sparql_Query2_Var('super'),
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$searchVar
);
} else {
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
$ggp->addTriple(
new Erfurt_Sparql_Query2_Var('super'),
new Erfurt_Sparql_Query2_IriRef($rel[0]),
$searchVar
);
$queryUnion->addElement($ggp);
}
}
$superUsed = true;
}
if ($superUsed) {
if ($backend == "zenddb") {
$elements[] = $queryUnion;
} else {
$queryOptional = new Erfurt_Sparql_Query2_OptionalGraphPattern();
$queryOptional->addElement($queryUnion);
$elements[] = $queryOptional;
}
$filter[] = new Erfurt_Sparql_Query2_Regex(
new Erfurt_Sparql_Query2_Str(new Erfurt_Sparql_Query2_Var('super')),
new Erfurt_Sparql_Query2_RDFLiteral('^' . EF_OWL_NS)
);
$filter[] = new Erfurt_Sparql_Query2_UnaryExpressionNot(
new Erfurt_Sparql_Query2_bound(
new Erfurt_Sparql_Query2_Var('super')
)
);
$elements[] = new Erfurt_Sparql_Query2_Filter(
new Erfurt_Sparql_Query2_ConditionalOrExpression($filter)
);
}
}
if (isset($setup->state->sorting)) {
$sortRel = new Erfurt_Sparql_Query2_IriRef($setup->state->sorting);
$sortVar = new Erfurt_Sparql_Query2_Var('sortRes');
$queryOptional = new Erfurt_Sparql_Query2_OptionalGraphPattern();
$queryOptional->addTriple(new Erfurt_Sparql_Query2_Var('resourceUri'), $sortRel, $sortVar);
$elements[] = $queryOptional;
}
return $elements;
}
}
================================================
FILE: extensions/navigation/NavigationModule.php
================================================
_session = $this->_owApp->session;
}
public function getTitle()
{
return "Navigation";
}
/**
* Returns the menu of the module
*
* @return string
*/
public function getMenu()
{
// check if menu must be shown
if (!$this->_privateConfig->defaults->showMenu) {
return new OntoWiki_Menu();
}
// build main menu (out of sub menus below)
$mainMenu = new OntoWiki_Menu();
// edit sub menu
if ($this->_owApp->erfurt->getAc()->isModelAllowed('edit', $this->_owApp->selectedModel)) {
$editMenu = new OntoWiki_Menu();
$editMenu->setEntry('Add Resource here', "javascript:navigationAddElement()");
$mainMenu->setEntry('Edit', $editMenu);
}
// count sub menu
$countMenu = new OntoWiki_Menu();
$countMenu->setEntry('10', "javascript:navigationEvent('setLimit', 10)")
->setEntry('20', "javascript:navigationEvent('setLimit', 20)")
->setEntry('30', "javascript:navigationEvent('setLimit', 30)");
// toggle sub menu
$toggleMenu = new OntoWiki_Menu();
// hidden elements
$toggleMenu->setEntry('Hidden Elements', "javascript:navigationEvent('toggleHidden')");
// empty elements
$toggleMenu->setEntry('Empty Elements', "javascript:navigationEvent('toggleEmpty')");
// implicit
$toggleMenu->setEntry('Implicit Elements', "javascript:navigationEvent('toggleImplicit')");
// view sub menu
$viewMenu = new OntoWiki_Menu();
$viewMenu->setEntry('Number of Elements', $countMenu);
$viewMenu->setEntry('Toggle Elements', $toggleMenu);
$viewMenu->setEntry('Reset Navigation', "javascript:navigationEvent('reset')");
$mainMenu->setEntry('View', $viewMenu);
// navigation type submenu
$sortMenu = new OntoWiki_Menu();
foreach ($this->_privateConfig->sorting->toArray() as $sortKey => $sortItem) {
$sortMenu->setEntry(
$sortItem['title'], "javascript:navigationEvent('setSort', '" . $sortItem['type'] . "')"
);
}
$mainMenu->setEntry('Sort', $sortMenu);
// navigation type submenu
$typeMenu = new OntoWiki_Menu();
foreach ($this->_privateConfig->config as $key => $config) {
if ($this->_privateConfig->defaults->checkTypes) {
if (isset($config->checkVisibility) && $config->checkVisibility == false) {
$typeMenu->setEntry($config->title, "javascript:navigationEvent('setType', '$key')");
} else {
if ($this->checkConfig($config) > 0) {
$typeMenu->setEntry($config->title, "javascript:navigationEvent('setType', '$key')");
}
}
} else {
$typeMenu->setEntry($config->title, "javascript:navigationEvent('setType', '$key')");
}
}
$mainMenu->setEntry('Type', $typeMenu);
return $mainMenu;
}
/**
* Returns the content
*/
public function getContents()
{
// scripts and css only if module is visible
$this->view->headScript()->appendFile($this->view->moduleUrl . 'navigation.js');
$this->view->headLink()->appendStylesheet($this->view->moduleUrl . 'navigation.css');
// this gives the complete config array as json to the javascript parts
$this->view->inlineScript()->prependScript(
'/* from modules/navigation/ */' . PHP_EOL .
'var navigationConfig = ' . json_encode($this->_privateConfig->toArray()) . ';' . PHP_EOL
);
// this gives the navigation session config to the javascript parts
if ($this->_session->navigation) {
$this->view->inlineScript()->prependScript(
'/* from modules/navigation/ */' . PHP_EOL .
'var navigationConfig = ' . json_encode($this->_privateConfig->toArray()) . ';' . PHP_EOL
);
}
$sessionKey = 'Navigation' . (isset($config->_session->identifier) ? $config->_session->identifier : '');
$stateSession = new Zend_Session_Namespace($sessionKey);
if (isset($stateSession) && ($stateSession->model == (string)$this->_owApp->selectedModel)) {
// load setup
$this->view->inlineScript()->prependScript(
'/* from modules/navigation/ */' . PHP_EOL .
'var navigationStateSetup = ' . $stateSession->setup . ';' . PHP_EOL
);
// load view
$this->view->stateView = $stateSession->view;
// set js actions
$this->view->inlineScript()->prependScript(
'$(document).ready(function() { navigationPrepareList(); } );' . PHP_EOL
);
}
// init view from scratch
$this->view->inlineScript()->prependScript(
'$(document).ready(function() { navigationEvent(\'init\'); } );' . PHP_EOL
);
$data['session'] = $this->_session->navigation;
// draw
$content = $this->render('navigation', $data, 'data'); //
// return content
return $content;
}
public function shouldShow()
{
return isset($this->_owApp->selectedModel);
}
private function checkConfig($config)
{
$resVar = new Erfurt_Sparql_Query2_Var('resourceUri');
$typeVar = new Erfurt_Sparql_Query2_IriRef(EF_RDF_TYPE);
$query = new Erfurt_Sparql_Query2();
$query->addProjectionVar($resVar)->setDistinct(true);
$union = new Erfurt_Sparql_Query2_GroupOrUnionGraphPattern();
if (is_string($config->hierarchyTypes)) {
$config->hierarchyTypes = array($config->hierarchyTypes);
}
foreach ($config->hierarchyTypes->toArray() as $type) {
$ggp = new Erfurt_Sparql_Query2_GroupGraphPattern();
$ggp->addTriple(
$resVar,
$typeVar,
new Erfurt_Sparql_Query2_IriRef($type)
);
$union->addElement($ggp);
}
$query->addElement($union);
$query->setLimit(1);
$allResults = $this->_owApp->selectedModel->sparqlQuery($query);
return count($allResults);
}
}
================================================
FILE: extensions/navigation/doap.n3
================================================
@prefix xsd: .
@prefix doap: .
@prefix rdfs: .
@prefix owconfig: .
@prefix extension: .
@prefix foaf: .
@prefix event: .
@prefix rdf: .
@prefix : .
<> foaf:primaryTopic :navigation .
:navigation a doap:Project ;
doap:name "navigation" ;
owconfig:privateNamespace ;
owconfig:enabled "true"^^xsd:boolean ;
rdfs:label "Navigation Module" ;
doap:description "an extensible and highly customizable module to navigate in knowledge bases via tree-based information (e.g. classes)" ;
owconfig:authorLabel "AKSW" ;
doap:maintainer ;
owconfig:templates "templates" ;
owconfig:languages "languages" ;
owconfig:hasModule :Default .
:Default a owconfig:Module ;
rdfs:label "Default" ;
owconfig:context "main.sidewindows" ;
owconfig:priority "30" .
:navigation owconfig:config [
a owconfig:Config;
owconfig:id "defaults";
:config "classes" ;
:limit "10" ;
:checkTypes "true"^^xsd:boolean ;
:showMenu "true"^^xsd:boolean
];
owconfig:config [
a owconfig:Config;
owconfig:id "sorting";
owconfig:config [
a owconfig:Config;
owconfig:id "label";
rdfs:label "By Label" ;
:type
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "config";
owconfig:config [
a owconfig:Config;
owconfig:id "sitenav";
rdfs:label "Site Navigation" ;
:titleMode "titleHelper" ;
:cache "false"^^xsd:boolean ;
:hierarchyTypes () ;
:checkVisibility "true"^^xsd:boolean ;
:showCounts "false"^^xsd:boolean ;
:checkSub "false"^^xsd:boolean ;
:hideDefaultHierarchy "false"^^xsd:boolean ;
:directLink "true"^^xsd:boolean ;
owconfig:config [
a owconfig:Config ;
owconfig:id "list" ;
:query "SELECT DISTINCT ?resourceUri WHERE { <%resource%> ?property ?resourceUri . ?property a . }" ;
];
owconfig:config [
a owconfig:Config ;
owconfig:id "query" ;
:top "SELECT DISTINCT ?resourceUri WHERE { ?resourceUri a . }" ;
:deeper "SELECT DISTINCT ?resourceUri WHERE { <%resource%> ?property ?resourceUri. ?resourceUri a }" ;
];
] ;
owconfig:config [
a owconfig:Config;
owconfig:id "classes";
rdfs:label "Classes" ;
:cache "false"^^xsd:boolean ;
:titleMode "titleHelper" ;
:checkVisibility "false"^^xsd:boolean ;
:hierarchyTypes (
) ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in () ;
];
owconfig:config [
a owconfig:Config;
owconfig:id "instanceRelation";
:out ()
];
:hiddenNS (
) ;
:hiddenRelation () ;
:showImplicitElements "true"^^xsd:boolean ;
:showEmptyElements "true"^^xsd:boolean ;
:showHiddenElements "false"^^xsd:boolean ;
:showCounts "false"^^xsd:boolean ;
:checkSub "true"^^xsd:boolean ;
:hideDefaultHierarchy "false"^^xsd:boolean ;
owconfig:config [
a owconfig:Config;
owconfig:id "list";
:config "{|filter|:[{|rdfsclass|:|%resource%|,|mode|:|rdfsclass|}]}"
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "properties";
rdfs:label "Properties" ;
:titleMode "titleHelper" ;
:hierarchyTypes (
) ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in ()
];
owconfig:config [
a owconfig:Config;
owconfig:id "instanceRelation";
:out ()
];
:showImplicitElements "false"^^xsd:boolean ;
:showEmptyElements "true"^^xsd:boolean ;
:showCounts "false"^^xsd:boolean ;
:hideDefaultHierarchy "false"^^xsd:boolean ;
:checkSub "true"^^xsd:boolean ;
owconfig:config [
a owconfig:Config;
owconfig:id "list";
:config "{|shownProperties|:[{|uri|:|%resource%|,|label|:|Label 1|,|action|:|add|,|inverse|:false}],|filter|:[{|property|:|%resource%|,|filter|:|bound|}]}"
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "spatial";
rdfs:label "Spatial" ;
:hierarchyTypes (
) ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in ()
];
owconfig:config [
a owconfig:Config;
owconfig:id "instanceRelation";
:out (
)
];
:titleMode "titleHelper"
];
owconfig:config [
a owconfig:Config;
owconfig:id "faun";
rdfs:label "Faunistics" ;
:hierarchyTypes (
) ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in ()
];
owconfig:config [
a owconfig:Config;
owconfig:id "instanceRelation";
:out ()
];
:titleMode "titleHelper" ;
:checkSub "true"^^xsd:boolean
];
owconfig:config [
a owconfig:Config;
owconfig:id "skos";
rdfs:label "SKOS" ;
:hierarchyTypes (
) ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in (
) ;
:out ()
];
:checkSub "true"^^xsd:boolean ;
:titleMode "titleHelper" ;
:showCounts "false"^^xsd:boolean
];
owconfig:config [
a owconfig:Config;
owconfig:id "org";
rdfs:label "Groups" ;
:hierarchyTypes (
) ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:out ()
];
owconfig:config [
a owconfig:Config;
owconfig:id "instanceRelation";
:in () ;
:out ()
];
:titleMode "titleHelper" ;
:showCounts "true"^^xsd:boolean
];
owconfig:config [
a owconfig:Config;
owconfig:id "go";
rdfs:label "Gene Ontology" ;
:hierarchyTypes () ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in ()
] ;
:titleMode "titleHelper" ;
:showCounts "false"^^xsd:boolean ;
:checkSub "true"^^xsd:boolean ;
:hideDefaultHierarchy "false"^^xsd:boolean ;
owconfig:config [
a owconfig:Config;
owconfig:id "list";
:query "SELECT DISTINCT ?resourceUri WHERE { ?resourceUri <%resource%> }"
]
];
owconfig:config [
a owconfig:Config;
owconfig:id "checklist";
rdfs:label "Checklist" ;
:titleMode "titleHelper" ;
:hierarchyTypes () ;
owconfig:config [
a owconfig:Config;
owconfig:id "hierarchyRelations";
:in ()
] ;
:checkSub "true"^^xsd:boolean ;
owconfig:config [
a owconfig:Config;
owconfig:id "list";
:shownProperties "{|uri|:|http://purl.org/net/faunistics#citationSuffix|,|label|:|citation suffix|,|action|:|add|,|inverse|:false}" ;
:query "SELECT DISTINCT ?resourceUri ?famUri WHERE { ?recUri ?resourceLocation OPTIONAL{ ?resourceLocation ?l1. OPTIONAL{ ?l1 ?l2. OPTIONAL{ ?l2 ?l3. } } } ?recUri ?resourceUri . ?resourceUri ?genUri . ?genUri ?famUri . FILTER ( sameTerm(?resourceLocation, <%resource%>) || sameTerm(?l1, <%resource%>) || sameTerm(?l2, <%resource%>) || sameTerm(?l3, <%resource%>)) }"
];
:rootName "Caucasus Spiders" ;
:rootURI ;
] ;
] .
:navigation doap:release :v1-0 .
:v1-0 a doap:Version ;
doap:revision "1.0" .
================================================
FILE: extensions/navigation/languages/navigation-de.csv
================================================
================================================
FILE: extensions/navigation/languages/navigation-en.csv
================================================
================================================
FILE: extensions/navigation/navigation.css
================================================
/*
* @copyright Copyright (c) 2014, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*/
.content h2.navRoot
{
font-size:1em;
font-weight:bold;
}
#navigation .icon { width:0.7em; }
#navigation .icon.icon-arrow-next
{
display:block;
font-size:1.5em !important;
width:1em; height:1em;
position:absolute;
right:0;
top:50%; margin-top:-0.5em;
/*top:0; height:100%;*/
background-color:#999;
background-image:url(icon-next.png);
-moz-border-radius:0.5em; border-radius:0.5em;
}
#navigation .icon.icon-arrow-previous { background-image:url(icon-previous.png); width:12px; }
#navigation .icon.icon-arrow-first { background-image:url(icon-first.png); width:8px; }
#navigation .navRoot.fancybuttons .icon.icon-arrow-previous
{
background-color:#999;
width:1.2em;
height:1.2em;
-moz-border-radius:0.6em;
border-radius:0.6em;
position:relative;
left:-0.25em;
}
#navigation .navRoot.fancybuttons .icon.icon-arrow-first
{
background-color:#bbb;
width:0.9em;
height:0.9em;
-moz-border-radius:0.45em;
border-radius:0.45em;
}
/* set contextmenu more left */
#navigation .has-contextmenus-block li a:hover span.button
{
right:1.75em;
}
#navigation a .icon, #navigation a.icon { opacity:0.4; }
#navigation a:hover .icon, #navigation a.icon:hover { opacity:0.6; text-decoration:none !important;}
#navigation a:hover .icon:hover { opacity:1; }
#navigation a span.navDeeperIcon { opacity:0.5; }
#navigation a span.navDeeperIcon:hover { opacity:1; }
#navigation .has-contextmenus-block li a
{
padding-right:1.75em;
}
================================================
FILE: extensions/navigation/navigation.js
================================================
/**
* This file is part of the navigation extension for OntoWiki
*
* @author Sebastian Tramp
* @copyright Copyright (c) 2009-2010, {@link http://aksw.org AKSW}
* @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
*
*/
(function(){
/**
* The main document.ready assignments and code
*/
$(document).ready(function() {
/* some used variables */
navigationContainer = $('#navigation-content');
navigationInput = $('#navigation-input');
navigationWindow = $('#navigation');
navigationExploreUrl = urlBase + 'navigation/explore';
navigationMoreUrl = urlBase + 'navigation/more';
navigationSaveUrl = urlBase + 'navigation/savestate';
navigationLoadUrl = urlBase + 'navigation/loadstate';
navigationListUrl = urlBase + 'list';
navSetup = '';
navigationInput.livequery('keypress', function(event) {
// do not create until user pressed enter
if ((event.which === 13) && (event.currentTarget.value !== '') ) {
navigationEvent('search', event.currentTarget.value);
$(event.currentTarget).val('');
return false;
} else if ( event.which === 13 ) {
return false;
}
return true;
});
if( typeof navigationStateSetup !== 'undefined'){
navigationSetup = navigationStateSetup;
}
});
/**
* Setups the Navgiation Parameters and start the request
*/
var navigationEvent = function (navEvent, eventParameter) {
var setup, navType;
/* init config when not existing or resetted by user */
if ((typeof navigationSetup === 'undefined') || (navEvent === 'reset') || (navEvent === 'setType')) {
// set the default or setType config
if (navEvent === 'setType') {
navType = eventParameter;
} else {
navType = navigationConfig.defaults.config;
}
var config = navigationConfig.config[navType];
// the limit
var limit = navigationConfig.defaults.limit;
// set the state
var state = {};
state.limit = limit;
state.path = [];
// pack state and config into setup value for post
setup = {'state': state, 'config': config};
} else {
setup = navigationSetup;
}
// delete old search string
delete(setup.state.searchString);
// nav event
switch (navEvent) {
case 'init':
// save hidden, implicit and empty to state
if(typeof navigationStateSetup !== 'undefined'){
if(typeof navigationStateSetup.state.showEmpty !== 'undefined'){
setup.state.showEmpty = navigationStateSetup.state.showEmpty;
}
if(typeof navigationStateSetup.state.showImplicit !== 'undefined'){
setup.state.showImplicit = navigationStateSetup.state.showImplicit;
}
if(typeof navigationStateSetup.state.showHidden !== 'undefined'){
setup.state.showHidden = navigationStateSetup.state.showHidden;
}
}else{
if(setup.config.showEmptyElements === '1'){
setup.state.showEmpty = true;
}
if(setup.config.showImplicitElements === '1'){
setup.state.showImplicit = true;
}
if(setup.config.showHiddenElements === '1'){
setup.state.showHidden = true;
}
}
// remove init sign and setup module title
navigationContainer.removeClass('init-me-please');
$('#navigation h1.title').text('Navigation: '+setup.config.title);
break;
case 'reset':
if(setup.config.showEmptyElements === '1'){
setup.state.showEmpty = true;
}
if(setup.config.showImplicitElements === '1'){
setup.state.showImplicit = true;
}
if(setup.config.showHiddenElements === '1'){
setup.state.showHidden = true;
}
case 'setType':
// remove init sign and setup module title
navigationContainer.removeClass('init-me-please');
$('#navigation h1.title').text('Navigation: '+setup.config.title);
break;
case 'refresh':
break;
case 'showResourceList':
setup.state.parent = eventParameter;
break;
case 'navigateDeeper':
// save path element
if ( typeof setup.state.parent !== 'undefined' ) {
setup.state.path.push(setup.state.parent);
}
// set new parent
setup.state.parent = eventParameter;
break;
case 'navigateHigher':
// count path elements
var pathlength = setup.state.path.length;
if ( typeof setup.state.parent === 'undefined' ) {
// we are at root level, so nothing higher than here
return;
}
if (pathlength === 0) {
// we are at the first sublevel (so we go to root)
delete(setup.state.parent);
} else {
// we are somewhere deeper ...
// set parent to the last path element
setup.state.parent = setup.state.path[pathlength-1];
// and delete the last path element
setup.state.path.pop();
}
break;
case 'navigateRoot':
// we are at root level, so nothing higher than here
// exception: after a search, it should be also rootable
if (typeof setup.state.parent === 'undefined' && setup.state.lastEvent !== 'search'){
return;
}
delete(setup.state.parent);
setup.state.path = [];
break;
case 'search':
setup.state.searchString = eventParameter;
break;
case 'setLimit':
setup.state.limit = eventParameter;
delete(setup.state.offset);
break;
case 'toggleHidden':
if (typeof setup.state.showHidden !== 'undefined') {
delete(setup.state.showHidden);
$('a[href=\'javascript:navigationEvent(\'toggleHidden\')\']').text('Show Hidden Elements');
} else {
setup.state.showHidden = true;
$('a[href=\'javascript:navigationEvent(\'toggleHidden\')\']').text('Hide Hidden Elements');
}
break;
case 'toggleEmpty':
// if no state is set, use default value from config
if ( typeof setup.state.showEmpty === 'undefined' ) {
if ( typeof setup.config.showEmptyElements !== 'undefined' ) {
setup.state.showEmpty = setup.config.showEmptyElements;
if(setup.state.showEmpty === true){
$('a[href=\'javascript:navigationEvent(\'toggleEmpty\')\']').text('Hide Empty Elements');
}
} else {
setup.state.showEmpty = true;
$('a[href=\'javascript:navigationEvent(\'toggleEmpty\')\']').text('Hide Empty Elements');
}
} else if (setup.state.showEmpty === false) {
setup.state.showEmpty = true;
$('a[href=\'javascript:navigationEvent(\'toggleEmpty\')\']').text('Hide Empty Elements');
} else {
setup.state.showEmpty = false;
$('a[href=\'javascript:navigationEvent(\'toggleEmpty\')\']').text('Show Empty Elements');
}
break;
case 'toggleImplicit':
// if no state is set, use default value from config
if (typeof setup.state.showImplicit === 'undefined') {
if (typeof setup.config.showImplicitElements !== 'undefined') {
setup.state.showImplicit = setup.config.showImplicitElements;
if (setup.state.showImplicit === true) {
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Hide Implicit Elements');
} else {
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Show Implicit Elements');
}
} else {
setup.state.showImplicit = true;
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Hide Implicit Elements');
}
} else if (setup.state.showImplicit === false) {
setup.state.showImplicit = true;
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Hide Implicit Elements');
} else {
setup.state.showImplicit = false;
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Show Implicit Elements');
}
break;
case 'more':
if( setup.state.offset !== undefined ){
setup.state.offset += 10;
}else{
setup.state.offset = parseInt(setup.state.limit, 10);
}
setup.state.limit = setup.state.offset;
break;
case 'setSort':
setup.state.sorting = eventParameter;
break;
default:
alert('error: unknown navigation event: '+navEvent);
return;
}
setup.state.lastEvent = navEvent;
navigationSetup = setup;
navSetup = setup;
navigationLoad (navEvent, setup);
return;
};
// expose
window.navigationEvent = navigationEvent;
/**
* request the navigation
*/
var navigationLoad = function (navEvent, setup) {
if (typeof setup === 'undefined') {
alert('error: No navigation setup given, but navigationLoad requested');
return;
}
// preparation of a callback function
var cbAfterLoad = function(){
$.post(navigationExploreUrl, {setup: $.toJSON(setup)},
function (data) {
//alert(data);
// only clear when there's no offset
if(typeof setup.state.offset === 'undefined' || setup.state.offset === 0) {
navigationContainer.empty();
} else if (setup.state.lastEvent === 'init') { // remove "show more" button on init event if we have offset
$('a.minibutton', navigationContainer).remove();
}
navigationContainer.append(data);
// remove the processing status
navigationInput.removeClass('is-processing');
switch (navEvent) {
case 'more':
navigationMore.remove();
// remove the processing status
navigationMore.removeClass('is-processing');
case 'refresh':
// no animation in refresh event (just the is processing)
break;
case 'navigateHigher':
navigationContainer.css('marginLeft', '-100%');
navigationContainer.animate({marginLeft:'0px'},'slow');
break;
case 'navigateDeeper':
navigationContainer.css('marginLeft', '100%');
navigationContainer.animate({marginLeft:'0px'},'slow');
break;
}
navigationPrepareList();
}
);
};
// first we set the processing status
navigationInput.addClass('is-processing');
navigationContainer.css('overflow', 'hidden');
switch (navEvent) {
case 'more':
navigationMore = $('#naviganion-more');
navigationMore.html(' ');
navigationMore.addClass('is-processing');
case 'refresh':
// no animation in refresh event (just the is processing)
cbAfterLoad();
break;
case 'navigateHigher':
navigationContainer.animate({marginLeft:'100%'},'slow', '', cbAfterLoad);
break;
case 'navigateDeeper':
navigationContainer.animate({marginLeft:'-100%'},'slow', '', cbAfterLoad);
break;
default:
//navigationContainer.slideUp('fast', cbAfterLoad);
cbAfterLoad();
}
return ;
};
var navigationPrepareToggles = function(){
if (navigationSetup.state.showHidden === true ) {
$('a[href=\'javascript:navigationEvent(\'toggleHidden\')\']').text('Hide Hidden Elements');
} else {
$('a[href=\'javascript:navigationEvent(\'toggleHidden\')\']').text('Show Hidden Elements');
}
// if no state is set, use default value from config
if (navigationSetup.state.showEmpty === true) {
$('a[href=\'javascript:navigationEvent(\'toggleEmpty\')\']').text('Hide Empty Elements');
} else {
$('a[href=\'javascript:navigationEvent(\'toggleEmpty\')\']').text('Show Empty Elements');
}
// if no state is set, use default value from config
if (navigationSetup.state.showImplicit === true) {
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Hide Implicit Elements');
} else {
$('a[href=\'javascript:navigationEvent(\'toggleImplicit\')\']').text('Show Implicit Elements');
}
};
/*
* This function creates navigation events
*/
var navigationPrepareList = function() {
//saveState();
// the links to deeper navigation entries
$('.navDeeper').click(function(event) {
navigationEvent('navigateDeeper', $(this).parent().attr('about'));
return false;
});
// the link to the root
$('.navFirst').click(function(event){
navigationEvent('navigateRoot');
return false;
});
// the link to higher level
$('.navBack').click(function(event){
navigationEvent('navigateHigher');
return false;
});
// the link to the instance list
$('.navList').click(function(event){
window.location.href = $(this).attr('href');
return false;
});
navigationPrepareToggles();
};
// expose
window.navigationPrepareList = navigationPrepareList;
/*
* Starts RDFauthor with a specific class init depending on position and config
*/
var navigationAddElement = function(){
// we use the first configured navigationType to create
var classResource = navigationSetup.config.hierarchyTypes[0];
// callback which manipulates the data given from the init json service
dataCallback = function(data) {
var config = navigationSetup.config; // configured navigation setup
var state = navigationSetup.state; // current navigation state
// subjectUri is the main resource
for (var newElementUri in data) {
break;
}
// check for parent element
if (typeof state.parent !== 'undefined') {
var parentUri = state.parent;
var relations = config.hierarchyRelations; // configured hierarchy relations
if (typeof relations.in !== 'undefined') {
// check for hierarchy relations (incoming eg. subClassOf)
var propertyUri = relations.in[0];
// TODO: this should be done by a future RDF/JSON API
data[newElementUri][propertyUri] = [ {'type' : 'uri' , 'value' : parentUri} ];
} else if (typeof relations.out !== 'undefined') {
// check for hierarchy relations (outgoing eg. skos:narrower)
var propertyUri = relations.out[0];
// TODO: this should be done by a future RDF/JSON API
var newStatement = {};
newStatement[propertyUri] = [{
'hidden': true ,
'type' : 'uri' ,
'value' : newElementUri
}];
data[parentUri] = newStatement;
}
}
// dont forget to return the manipulated data
return data;
};
// start RDFauthor
createInstanceFromClassURI(classResource, dataCallback);
}
// expose
window.navigationAddElement = navigationAddElement;
})();
================================================
FILE: extensions/navigation/navigation.phtml
================================================