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. [![Travis CI Build Status](https://travis-ci.org/AKSW/OntoWiki.svg)](https://travis-ci.org/AKSW/OntoWiki/) [![Latest Stable Version](https://poser.pugx.org/aksw/ontowiki/v/stable)](https://packagist.org/packages/aksw/ontowiki) [![Total Downloads](https://poser.pugx.org/aksw/ontowiki/downloads)](https://packagist.org/packages/aksw/ontowiki) [![License](https://poser.pugx.org/aksw/ontowiki/license)](https://packagist.org/packages/aksw/ontowiki) [![composer.lock](https://poser.pugx.org/aksw/ontowiki/composerlock)](https://packagist.org/packages/aksw/ontowiki) [![OntoWiki User Documentation](https://cdn.rawgit.com/AKSW/OntoWiki/develop/application/logo/user_doc.svg)](https://docs.ontowiki.net) [![OntoWiki API Documentation](https://cdn.rawgit.com/AKSW/OntoWiki/develop/application/logo/api_doc.svg)](http://api.ontowiki.net/) ![](https://raw.github.com/wiki/AKSW/OntoWiki/images/owHeader.png) ## 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). ![Screenshot](http://lh4.ggpht.com/-kXpKMqBBCIU/Tpx45SUaItI/AAAAAAAAA9w/aPYaNQjcpvo/s800/ontowiki.png) ## 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.1 To comment on this schema, please contact dcmifb@dublincore.org. The Dublin Core Metadata Initiative 2008-01-14 Title A name given to the resource. 1999-07-02 2008-01-14 A 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. Creator An 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-02 2008-01-14 A 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. Subject The 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-02 2008-01-14 A 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. Description An 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-02 2008-01-14 A 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. Publisher An 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-02 2008-01-14 A 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. Contributor An 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-02 2008-01-14 A 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. Date A 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-02 2008-01-14 A 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. Type The 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-02 2008-01-14 A 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. Format The 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-02 2008-01-14 A 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. Identifier An 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-02 2008-01-14 A 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. Source A 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-02 2008-01-14 A 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. Language A language of the resource. Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646]. 1999-07-02 2008-01-14 A 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. Relation A related resource. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. 1999-07-02 2008-01-14 A 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. Coverage The 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-02 2008-01-14 A 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. Rights Information 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-02 2008-01-14 A 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/ namespace To comment on this schema, please contact dcmifb@dublincore.org. The Dublin Core Metadata Initiative 2008-01-14 Title A name given to the resource. 2008-01-14 2008-01-14 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. Creator An 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-14 2008-01-14 Subject The 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-14 2008-01-14 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. Description An 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-14 2008-01-14 Publisher An 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-14 2008-01-14 Contributor An 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-14 2008-01-14 Date A 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-14 2008-01-14 Type The 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-14 2008-01-14 Format The 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-14 2008-01-14 Identifier An 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-14 2008-01-14 Source A 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-14 2008-01-14 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. Language A language of the resource. Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646]. 2008-01-14 2008-01-14 Relation A related resource. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. 2008-01-14 2008-01-14 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. Coverage The 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-14 2008-01-14 Rights Information 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-14 2008-01-14 Audience A class of entity for whom the resource is intended or useful. 2001-05-21 2008-01-14 Alternative Title An alternative name for the resource. The distinction between titles and alternative titles is application-specific. 2000-07-11 2008-01-14 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. Table Of Contents A list of subunits of the resource. 2000-07-11 2008-01-14 Abstract A summary of the resource. 2000-07-11 2008-01-14 Date Created Date of creation of the resource. 2000-07-11 2008-01-14 Date Valid Date (often a range) of validity of a resource. 2000-07-11 2008-01-14 Date Available Date (often a range) that the resource became or will become available. 2000-07-11 2008-01-14 Date Issued Date of formal issuance (e.g., publication) of the resource. 2000-07-11 2008-01-14 Date Modified Date on which the resource was changed. 2000-07-11 2008-01-14 Extent The size or duration of the resource. 2000-07-11 2008-01-14 Medium The material or physical carrier of the resource. 2000-07-11 2008-01-14 Is Version Of A 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-11 2008-01-14 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. Has Version A related resource that is a version, edition, or adaptation of the described resource. 2000-07-11 2008-01-14 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. Is Replaced By A related resource that supplants, displaces, or supersedes the described resource. 2000-07-11 2008-01-14 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. Replaces A related resource that is supplanted, displaced, or superseded by the described resource. 2000-07-11 2008-01-14 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. Is Required By A related resource that requires the described resource to support its function, delivery, or coherence. 2000-07-11 2008-01-14 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. Requires A related resource that is required by the described resource to support its function, delivery, or coherence. 2000-07-11 2008-01-14 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. Is Part Of A related resource in which the described resource is physically or logically included. 2000-07-11 2008-01-14 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. Has Part A related resource that is included either physically or logically in the described resource. 2000-07-11 2008-01-14 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. Is Referenced By A related resource that references, cites, or otherwise points to the described resource. 2000-07-11 2008-01-14 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. References A related resource that is referenced, cited, or otherwise pointed to by the described resource. 2000-07-11 2008-01-14 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. Is Format Of A related resource that is substantially the same as the described resource, but in another format. 2000-07-11 2008-01-14 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. Has Format A related resource that is substantially the same as the pre-existing described resource, but in another format. 2000-07-11 2008-01-14 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. Conforms To An established standard to which the described resource conforms. 2001-05-21 2008-01-14 Spatial Coverage Spatial characteristics of the resource. 2000-07-11 2008-01-14 Temporal Coverage Temporal characteristics of the resource. 2000-07-11 2008-01-14 Mediator An 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-21 2008-01-14 Date Accepted Date 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-13 2008-01-14 Date Copyrighted Date of copyright. 2002-07-13 2008-01-14 Date Submitted Date 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-13 2008-01-14 Audience Education Level A class of entity, defined in terms of progression through an educational or training context, for which the described resource is intended. 2002-07-13 2008-01-14 Access Rights Information 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-15 2008-01-14 Bibliographic Citation A bibliographic reference for the resource. Recommended practice is to include sufficient bibliographic detail to identify the resource as unambiguously as possible. 2003-02-15 2008-01-14 License A legal document giving official permission to do something with the resource. 2004-06-14 2008-01-14 Rights Holder A person or organization owning or managing rights over the resource. 2004-06-14 2008-01-14 Provenance A 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-20 2008-01-14 Instructional Method A 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-13 2008-01-14 Accrual Method The method by which items are added to a collection. 2005-06-13 2008-01-14 Accrual Periodicity The frequency with which items are added to a collection. 2005-06-13 2008-01-14 Accrual Policy The policy governing the addition of items to a collection. 2005-06-13 2008-01-14 Agent A resource that acts or has the power to act. Examples of Agent include person, organization, and software agent. 2008-01-14 Agent Class A group of agents. Examples of Agent Class include groups seen as classes, such as students, women, charities, lecturers. 2008-01-14 Bibliographic Resource A book, article, or other documentary resource. 2008-01-14 File Format A digital resource format. Examples include the formats defined by the list of Internet Media Types. 2008-01-14 Frequency A rate at which something recurs. 2008-01-14 Jurisdiction The extent or range of judicial, law enforcement, or other authority. 2008-01-14 License Document A legal document giving official permission to do something with a Resource. 2008-01-14 Linguistic System A system of signs, symbols, sounds, gestures, or rules used in communication. Examples include written, spoken, sign, and computer languages. 2008-01-14 Location A spatial region or named place. 2008-01-14 Location, Period, or Jurisdiction A location, period of time, or jurisdiction. 2008-01-14 Media Type A file format or physical medium. 2008-01-14 Media Type or Extent A media type or extent. 2008-01-14 Method of Instruction A process that is used to engender knowledge, attitudes, and skills. 2008-01-14 Method of Accrual A method by which resources are added to a collection. 2008-01-14 Period of Time An interval of time that is named or defined by its start and end dates. 2008-01-14 Physical Medium A physical material or carrier. Examples include paper, canvas, or DVD. 2008-01-14 Physical Resource A material thing. 2008-01-14 Policy A plan or course of action by an authority, intended to influence and determine decisions, actions, and other matters. 2008-01-14 Provenance Statement A 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-14 Rights Statement A 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-14 Size or Duration A 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-14 Standard A basis for comparison; a reference point against which other things can be evaluated. 2008-01-14 ISO 639-2 The three-letter alphabetic codes listed in ISO639-2 for the representation of names of languages. 2000-07-11 2008-01-14 RFC 1766 The set of tags, constructed according to RFC 1766, for the identification of languages. 2000-07-11 2008-01-14 URI The set of identifiers constructed according to the generic syntax for Uniform Resource Identifiers as specified by the Internet Engineering Task Force. 2000-07-11 2008-01-14 DCMI Point The set of points in space defined by their geographic coordinates according to the DCMI Point Encoding Scheme. 2000-07-11 2008-01-14 ISO 3166 The set of codes listed in ISO 3166-1 for the representation of names of countries. 2000-07-11 2008-01-14 DCMI Box The set of regions in space defined by their geographic coordinates according to the DCMI Box Encoding Scheme. 2000-07-11 2008-01-14 DCMI Period The set of time intervals defined by their limits according to the DCMI Period Encoding Scheme. 2000-07-11 2008-01-14 W3C-DTF The set of dates and times constructed according to the W3C Date and Time Formats Specification. 2000-07-11 2008-01-14 RFC 3066 The set of tags constructed according to RFC 3066 for the identification of languages. RFC 3066 has been obsoleted by RFC 4646. 2002-07-13 2008-01-14 RFC 4646 The set of tags constructed according to RFC 4646 for the identification of languages. RFC 4646 obsoletes RFC 3066. 2008-01-14 ISO 639-3 The set of three-letter codes listed in ISO 639-3 for the representation of names of languages. 2008-01-14 LCSH The set of labeled concepts specified by the Library of Congress Subject Headings. 2000-07-11 2008-01-14 MeSH The set of labeled concepts specified by the Medical Subject Headings. 2000-07-11 2008-01-14 DDC The set of conceptual resources specified by the Dewey Decimal Classification. 2000-07-11 2008-01-14 LCC The set of conceptual resources specified by the Library of Congress Classification. 2000-07-11 2008-01-14 UDC The set of conceptual resources specified by the Universal Decimal Classification. 2000-07-11 2008-01-14 DCMI Type Vocabulary The set of classes specified by the DCMI Type Vocabulary, used to categorize the nature or genre of the resource. 2000-07-11 2008-01-14 IMT The set of media types specified by the Internet Assigned Numbers Authority. 2000-07-11 2008-01-14 TGN The set of places specified by the Getty Thesaurus of Geographic Names. 2000-07-11 2008-01-14 NLM The set of conceptual resources specified by the National Library of Medicine Classification. 2005-06-13 2008-01-14 ================================================ FILE: application/config/SysBase/foaf ================================================ ================================================ FILE: application/config/SysBase/geo ================================================ WGS84 Geo Positioning: an RDF vocabulary A 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 SpatialThing Anything with spatial extent, i.e. size, shape, or position. e.g. people, places, bowling balls, as well as abstract areas like cubes. Point A 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). latitude The WGS84 latitude of a SpatialThing (decimal degrees). longitude The WGS84 longitude of a SpatialThing (decimal degrees). altitude The WGS84 altitude of a SpatialThing (decimal meters above the local reference ellipsoid). lat/long A 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 $ Class Thing Nothing equivalentClass disjointWith equivalentProperty sameAs differentFrom AllDifferent distinctMembers unionOf intersectionOf complementOf oneOf Restriction onProperty allValuesFrom hasValue someValuesFrom minCardinality maxCardinality cardinality ObjectProperty DatatypeProperty inverseOf TransitiveProperty SymmetricProperty FunctionalProperty InverseFunctionalProperty AnnotationProperty Ontology OntologyProperty imports versionInfo priorVersion backwardCompatibleWith incompatibleWith DeprecatedClass DeprecatedProperty DataRange ================================================ FILE: application/config/SysBase/rdf ================================================ The RDF Vocabulary (RDF) This is the RDF Schema for the RDF vocabulary defined in the RDF namespace. type The subject is an instance of a class. Property The class of RDF properties. Statement The class of RDF statements. subject The subject of the subject RDF statement. predicate The predicate of the subject RDF statement. object The object of the subject RDF statement. Bag The class of unordered containers. Seq The class of ordered containers. Alt The class of containers of alternatives. value Idiomatic property used for structured values. List The class of RDF Lists. nil The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it. first The first item in the subject RDF list. rest The rest of the subject RDF list after the first item. XMLLiteral The class of XML literal values. ================================================ FILE: application/config/SysBase/rdfs ================================================ Resource The class resource, everything. Class The class of classes. subClassOf The subject is a subclass of a class. subPropertyOf The subject is a subproperty of a property. comment A description of the subject resource. label A human-readable name for the subject. domain A domain of the subject property. range A range of the subject property. seeAlso Further information about the subject resource. isDefinedBy The defininition of the subject resource. Literal The class of literal values, eg. textual strings and integers. Container The class of RDF containers. ContainerMembershipProperty The class of container membership properties, rdf:_1, rdf:_2, ..., all of which are sub-properties of 'member'. member A member of the subject resource. Datatype The class of RDF datatypes. ================================================ FILE: application/config/SysBase/rel ================================================ text/html HTML application/json JSON text/plain Turtle RELATIONSHIP: A vocabulary for describing relationships between people A vocabulary for describing relationships between people http://purl.org/vocab/relationship/rel-vocab-20050810 http://purl.org/vocab/relationship rel 2004-02-11 Ian Davis Eric Vitiello Jr Using With FOAF Using With HTML and XHTML Added isDefinedBy properties and updated documentation 2005-08-10 Ian Davis Typed vocabulary as owl:Ontology 2009-05-15 Ian Davis friend of A person who shares mutual friendship with this person. acquaintance of A person having more than slight or superficial knowledge of this person but short of friendship. parent of A person who has given birth to or nurtured and raised this person. sibling of A person having one or both parents in common with this person. child of A person who was given birth to or nurtured and raised by this person. grandchild of Grandchild Of A person who is a child of any of this person's children. spouse of A person who is married to this person enemy of A person towards whom this person feels hatred, intends injury to, or opposes the interests of. antagonist of A person who opposes and contends against this person. ambivalent of A person towards whom this person has mixed feelings or emotions. lost contact with A person who was once known by this person but has subsequently become uncontactable. knows of A person who has come to be known to this person through their actions or position. would like to now A person whom this person would desire to know more closely. knows in passing A person whom this person has slight or superficial knowledge of. knows by reputation A person known by this person primarily for a particular action, position or field of endeavour. close friend of A person who shares a close mutual friendship with this person. has met A person who has met this person whether in passing or longer. works with A person who works for the same employer as this person. colleague of A person who is a member of the same profession as this person. collaborates with A person who works towards a common goal with this person. employer of A person who engages the services of this person. employed by A person for whom this person's services have been engaged. mentor of A person who serves as a trusted counselor or teacher to this person. apprentice to A person to whom this person serves as a trusted counselor or teacher. lives with A person who shares a residence with this person. neighbor of A person who lives in the same locality as this person. grandparent of A person who is the parent of any of this person's parents. life partner of A person who has made a long-term commitment to this person's. engaged to A person to whom this person is betrothed. ancestor of A person who is a descendant of this person. Descendant Of descendant of A person from whom this person is descended. relationship A particular type of connection existing between people related to or having dealings with each other. participant in participant influenced by a person who has influenced this person. ================================================ FILE: application/config/SysBase/sioc ================================================ SIOC Core Ontology Namespace Revision: 1.31 SIOC (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. Community Community is a high-level concept that defines an online community and what it consists of. Container An area in which content Items are contained. Forum A discussion area on which Posts or entries are made. Item An Item is something which can be in a Container. Post An article or message that can be posted to a Forum. Role A Role is a function of a User within a scope of a particular Forum, Site, etc. Space A Space is a place where data resides, e.g. on a website, desktop, fileshare, etc. Site A 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. Thread A container for a series of threaded discussion Posts or Items. User A User account in an online community site. Usergroup A set of User accounts whose owners have a common purpose or interest. Can be used for access control purposes. about Specifies that this Item is about a particular resource, e.g. a Post describing a book, hotel, etc. account_of Refers to the foaf:Agent or foaf:Person who owns this sioc:User online account. administrator_of A Site that the User is an administrator of. attachment The URI of a file attached to an Item. avatar An image or depiction used to represent this User. container_of An Item that this Container contains. content The content of the Item in plain text format. creator_of A resource that the User is a creator of. Links to a previous (older) revision of this Item or Post. earlier_version email An electronic mail address of the User. email_sha1 An electronic mail address of the User, encoded using SHA1. feed A feed (e.g. RSS, Atom, etc.) pertaining to this resource (e.g. for a Forum, Site, User, etc.). follows Indicates that one User follows another User (e.g. for microblog posts or other content item updates). function_of A User who has this Role. has_administrator A User who is an administrator of this Site. has_container The Container to which this Item belongs. has_creator This is the User who made this resource. has_function A Role that this User has. has_host The Site that hosts this Forum. has_member A User who is a member of this Usergroup. has_moderator A User who is a moderator of this Forum. has_modifier A User who modified this Item. has_owner A User that this resource is owned by. has_parent A Container or Forum that this Container or Forum is a child of. has_reply Points to an Item or Post that is a reply or response to this Item or Post. has_scope A resource that this Role applies to. has_space A data Space which this resource is a part of. has_subscriber A User who is subscribed to this Container. has_usergroup Points to a Usergroup that has certain access to this Space. host_of A Forum that is hosted on this Site. id An 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_address The 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_version Links to the latest revision of this Item or Post. latest_version link A URI of a document which contains this SIOC object. links_to Links extracted from hyperlinks within a SIOC concept, e.g. Post or Site. member_of A Usergroup that this User is a member of. moderator_of A Forum that User is a moderator of. modifier_of An Item that this User has modified. name The name of a SIOC instance, e.g. a username for a User, group name for a Usergroup, etc. next_by_date Next Item or Post in a given Container sorted by date. next_version Links to the next revision of this Item or Post. note A note associated with this resource, for example, if it has been edited by a User. num_replies The number of replies that this Item, Thread, Post, etc. has. Useful for when the reply structure is absent. num_views The number of times this Item, Thread, User profile, etc. has been viewed. owner_of A resource owned by a particular User, for example, a weblog or image gallery. parent_of A child Container or Forum that this Container or Forum is a parent of. previous_by_date Previous Item or Post in a given Container sorted by date. previous_version Links to the previous revision of this Item or Post. related_to Related Posts for this Post, perhaps determined implicitly from topics or references. reply_of Links to an Item or Post which this Item or Post is a reply to. scope_of A Role that has a scope of this resource. sibling An 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_of A resource which belongs to this data Space. subscriber_of A Container that a User is subscribed to. topic A topic of interest, linking to the appropriate URI, e.g. in the Open Directory Project or of a SKOS category. usergroup_of A Space that the Usergroup has access to. title This 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_encoded The 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_at When this was created, in ISO 8601 format. This property is deprecated. Use dcterms:created from the Dublin Core ontology instead. description The content of the Post. This property is deprecated. Use sioc:content or other methods (AtomOwl, content:encoded from RSS 1.0, etc.) instead. first_name First (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_of This property has been renamed. Use sioc:usergroup_of instead. The discussion that is related to this Item. has_discussion has_group This property has been renamed. Use sioc:has_usergroup instead. has_part An resource that is a part of this subject. This property is deprecated. Use dcterms:hasPart from the Dublin Core ontology instead. last_name Last (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_at When this was modified, in ISO 8601 format. This property is deprecated. Use dcterms:modified from the Dublin Core ontology instead. part_of A resource that the subject is a part of. This property is deprecated. Use dcterms:isPartOf from the Dublin Core ontology instead. reference Links either created explicitly or extracted implicitly on the HTML level from the Post. Renamed to sioc:links_to. subject Keyword(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 Namespace Extends the SIOC Core Ontology (Semantically-Interlinked Online Communities) by defining subclasses and subproperties of SIOC terms. Address Book Describes a collection of personal or organisational addresses. Annotation Set Describes a set of annotations, for example, those created by a particular user or related to a particular topic. Audio Channel Describes a channel for distributing audio or sound files, for example, a podcast. Bookmark Folder Describes a shared collection of bookmarks. Briefcase Describes a briefcase or file service. Event Calendar Describes a calendar of events. Image Gallery Describes an image gallery, for example, a photo album. Project Directory Describes a project directory. Resume Bank Describes a collection of resumes. Review Area Describes an area where reviews are posted. Subscription List Describes a shared set of feed subscriptions. Survey Collection Describes an area where survey data can be collected, e.g. from polls. Video Channel Describes a channel for distributing videos (moving image) files, for example, a video podcast. Wiki Describes a wiki space. Favourite Things Describes a list or a collection of one's favourite things. Offer List Describes a list of the items someone has available to offer. Playlist Describes a list of media items that have been played or can be played. Reading List Describes a list of books or other materials that have been read or are suggested for reading. Wish List Describes a list of the items someone wishes to get. Argumentative Discussion Describes a discussion area where logical arguments can take place. Chat Channel Describes a channel for chat or instant messages, for example, via IRC or IM. Mailing List Describes an electronic mailing list. Message Board Describes a message board, also known as an online bulletin board or discussion forum. Microblog Describes a microblog, i.e. a blog consisting of short text messages. Weblog Describes a weblog (blog), i.e. an online journal. Poll Describes a posted item that contains a poll or survey content. Blog Post Describes a post that is specifically made on a weblog. Board Post Describes a post that is specifically made on a message board. Comment Comment 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 Message Describes an instant message, e.g. sent via Jabber. Mail Message Describes an electronic mail message, e.g. a post sent to a mailing list. Microblog Post Describes a post that is specifically made on a microblog. Wiki Article Describes a wiki article. Answer A Post that provides an answer in reply to a Question. Best Answer A 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. Question A Post that asks a Question. Category Category is used on the object of sioc:topic to indicate that this resource is a category on a site. Tag Tag 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 Vocabulary Dave Beckett Nikki Rogers Participants 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 Miles Sean Bechhofer Concept An idea or notion; a unit of thought. Concept Scheme A 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. Collection A 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 Collection An 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 scheme Relates 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 concept Relates, 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 scheme Relates a concept to the concept scheme that it is a top level concept of. preferred label The 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 label An 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 label A 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. notation A 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. note A general note, for any purpose. This property may be used directly, or as a super-property for more specific note types. change note A note about a modification to a concept. definition A statement or formal explanation of the meaning of a concept. editorial note A note for an editor, translator or maintainer of the vocabulary. example An example of the use of a concept. history note A note about the past state/use/meaning of a concept. scope note A note that helps to clarify the meaning and/or the use of a concept. is in semantic relation with Links 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 concept Relates 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 concept Relates 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 concept Relates a concept to a concept with which there is an associative semantic relationship. skos:related is disjoint with skos:broaderTransitive has broader transitive skos: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 transitive skos: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 member Relates a collection to one of its members. has member list Relates 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 with Relates two concepts coming, by convention, from different schemes, and that have comparable meanings These 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 match skos:broadMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes. has narrower match skos:narrowMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes. has related match skos:relatedMatch is used to state an associative mapping link between two conceptual resources in different concept schemes. has exact match skos: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 match skos: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 Ayers Seth Russell Richard Newman An 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 ontology 2005-03-23 2005-05-19 2005-11-27 2005-12-21 A Tagging which has precisely one associated resource, and one associated tag. 1 1 A 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. testing The object is a Tag which plays a role in the subject Tagging. testing The 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. testing Indicates 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. testing The 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. testing The subject Tagging occurred at the subject time and date. testing The object is a resource which plays a role in the subject Tagging. testing Indicates 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. type The subject is an instance of a class. Property The class of RDF properties. Statement The class of RDF statements. subject The subject of the subject RDF statement. predicate The predicate of the subject RDF statement. object The object of the subject RDF statement. Bag The class of unordered containers. Seq The class of ordered containers. Alt The class of containers of alternatives. value Idiomatic property used for structured values. List The class of RDF Lists. nil The empty list, with no items in it. If the rest of a list is nil then the list has no more items in it. first The first item in the subject RDF list. rest The rest of the subject RDF list after the first item. XMLLiteral The class of XML literal values. Resource The class resource, everything. Class The class of classes. subClassOf The subject is a subclass of a class. subPropertyOf The subject is a subproperty of a property. comment A description of the subject resource. label A human-readable name for the subject. domain A domain of the subject property. range A range of the subject property. seeAlso Further information about the subject resource. isDefinedBy The defininition of the subject resource. Literal The class of literal values, eg. textual strings and integers. Container The class of RDF containers. ContainerMembershipProperty The class of container membership properties, rdf:_1, rdf:_2, ..., all of which are sub-properties of 'member'. member A member of the subject resource. Datatype The class of RDF datatypes. Class Thing Nothing equivalentClass disjointWith equivalentProperty sameAs differentFrom AllDifferent distinctMembers unionOf intersectionOf complementOf oneOf Restriction onProperty allValuesFrom hasValue someValuesFrom minCardinality maxCardinality cardinality ObjectProperty DatatypeProperty inverseOf TransitiveProperty SymmetricProperty FunctionalProperty InverseFunctionalProperty AnnotationProperty Ontology OntologyProperty imports versionInfo priorVersion backwardCompatibleWith incompatibleWith DeprecatedClass DeprecatedProperty DataRange Title A name given to the resource. Creator An 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. Subject The 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. Description An 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. Publisher An 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. Contributor An 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. Date A 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]. Type The 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. Format The 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]. Identifier An 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. Source A 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. Language A language of the resource. Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646]. Relation A related resource. Recommended best practice is to identify the related resource by means of a string conforming to a formal identification system. Coverage The 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. Rights Information 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. Title A 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. Creator An 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. Subject The 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. Description An 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. Publisher An 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. Contributor An 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. Date A 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]. Type The 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. Format The 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]. Identifier An 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. Source A 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. Language A language of the resource. Recommended best practice is to use a controlled vocabulary such as RFC 4646 [RFC4646]. Relation A 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. Coverage The 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. Rights Information 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. Audience A class of entity for whom the resource is intended or useful. 2001-05-21 Alternative Title An alternative name for the resource. The distinction between titles and alternative titles is application-specific. 2000-07-11 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. Table Of Contents A list of subunits of the resource. 2000-07-11 Abstract A summary of the resource. 2000-07-11 Date Created Date of creation of the resource. 2000-07-11 Date Valid Date (often a range) of validity of a resource. 2000-07-11 Date Available Date (often a range) that the resource became or will become available. 2000-07-11 Date Issued Date of formal issuance (e.g., publication) of the resource. 2000-07-11 Date Modified Date on which the resource was changed. 2000-07-11 Extent The size or duration of the resource. 2000-07-11 Medium The material or physical carrier of the resource. 2000-07-11 Is Version Of A 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-11 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. Has Version A related resource that is a version, edition, or adaptation of the described resource. 2000-07-11 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. Is Replaced By A related resource that supplants, displaces, or supersedes the described resource. 2000-07-11 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. Replaces A related resource that is supplanted, displaced, or superseded by the described resource. 2000-07-11 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. Is Required By A related resource that requires the described resource to support its function, delivery, or coherence. 2000-07-11 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. Requires A related resource that is required by the described resource to support its function, delivery, or coherence. 2000-07-11 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. Is Part Of A related resource in which the described resource is physically or logically included. 2000-07-11 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. Has Part A related resource that is included either physically or logically in the described resource. 2000-07-11 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. Is Referenced By A related resource that references, cites, or otherwise points to the described resource. 2000-07-11 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. References A related resource that is referenced, cited, or otherwise pointed to by the described resource. 2000-07-11 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. Is Format Of A related resource that is substantially the same as the described resource, but in another format. 2000-07-11 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. Has Format A related resource that is substantially the same as the pre-existing described resource, but in another format. 2000-07-11 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. Conforms To An established standard to which the described resource conforms. 2001-05-21 Spatial Coverage Spatial characteristics of the resource. 2000-07-11 Temporal Coverage Temporal characteristics of the resource. 2000-07-11 Mediator An 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-21 Date Accepted Date 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-13 Date Copyrighted Date of copyright. 2002-07-13 Date Submitted Date 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-13 Audience Education Level A class of entity, defined in terms of progression through an educational or training context, for which the described resource is intended. 2002-07-13 Access Rights Information 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-15 Bibliographic Citation A bibliographic reference for the resource. Recommended practice is to include sufficient bibliographic detail to identify the resource as unambiguously as possible. 2003-02-15 License A legal document giving official permission to do something with the resource. 2004-06-14 Rights Holder A person or organization owning or managing rights over the resource. 2004-06-14 Provenance A 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-20 Instructional Method A 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-13 Accrual Method The method by which items are added to a collection. 2005-06-13 Accrual Periodicity The frequency with which items are added to a collection. 2005-06-13 Accrual Policy The policy governing the addition of items to a collection. 2005-06-13 Agent A resource that acts or has the power to act. Examples of Agent include person, organization, and software agent. Agent Class A group of agents. Examples of Agent Class include groups seen as classes, such as students, women, charities, lecturers. Bibliographic Resource A book, article, or other documentary resource. File Format A digital resource format. Examples include the formats defined by the list of Internet Media Types. Frequency A rate at which something recurs. Jurisdiction The extent or range of judicial, law enforcement, or other authority. License Document A legal document giving official permission to do something with a Resource. Linguistic System A system of signs, symbols, sounds, gestures, or rules used in communication. Examples include written, spoken, sign, and computer languages. Location A spatial region or named place. Location, Period, or Jurisdiction A location, period of time, or jurisdiction. Media Type A file format or physical medium. Media Type or Extent A media type or extent. Method of Instruction A process that is used to engender knowledge, attitudes, and skills. Method of Accrual A method by which resources are added to a collection. Period of Time An interval of time that is named or defined by its start and end dates. Physical Medium A physical material or carrier. Examples include paper, canvas, or DVD. Physical Resource A material thing. Policy A plan or course of action by an authority, intended to influence and determine decisions, actions, and other matters. Provenance Statement A statement of any changes in ownership and custody of a resource since its creation that are significant for its authenticity, integrity, and interpretation. Rights Statement A 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 Duration A 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. Standard A basis for comparison; a reference point against which other things can be evaluated. ISO 639-2 The three-letter alphabetic codes listed in ISO639-2 for the representation of names of languages. 2000-07-11 RFC 1766 The set of tags, constructed according to RFC 1766, for the identification of languages. 2000-07-11 URI The set of identifiers constructed according to the generic syntax for Uniform Resource Identifiers as specified by the Internet Engineering Task Force. 2000-07-11 DCMI Point The set of points in space defined by their geographic coordinates according to the DCMI Point Encoding Scheme. 2000-07-11 ISO 3166 The set of codes listed in ISO 3166-1 for the representation of names of countries. 2000-07-11 DCMI Box The set of regions in space defined by their geographic coordinates according to the DCMI Box Encoding Scheme. 2000-07-11 DCMI Period The set of time intervals defined by their limits according to the DCMI Period Encoding Scheme. 2000-07-11 W3C-DTF The set of dates and times constructed according to the W3C Date and Time Formats Specification. 2000-07-11 RFC 3066 The set of tags constructed according to RFC 3066 for the identification of languages. RFC 3066 has been obsoleted by RFC 4646. 2002-07-13 RFC 4646 The set of tags constructed according to RFC 4646 for the identification of languages. RFC 4646 obsoletes RFC 3066. ISO 639-3 The set of three-letter codes listed in ISO 639-3 for the representation of names of languages. Concept An idea or notion; a unit of thought. Concept Scheme A 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. Collection A 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 Collection An 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 scheme Relates 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 concept Relates, 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 scheme Relates a concept to the concept scheme that it is a top level concept of. preferred label The 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 label An 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 label A 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. notation A 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. note A general note, for any purpose. This property may be used directly, or as a super-property for more specific note types. change note A note about a modification to a concept. definition A statement or formal explanation of the meaning of a concept. editorial note A note for an editor, translator or maintainer of the vocabulary. example An example of the use of a concept. history note A note about the past state/use/meaning of a concept. scope note A note that helps to clarify the meaning and/or the use of a concept. is in semantic relation with Links 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 concept Relates 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 concept Relates 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 concept Relates a concept to a concept with which there is an associative semantic relationship. skos:related is disjoint with skos:broaderTransitive has broader transitive skos: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 transitive skos: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 member Relates a collection to one of its members. has member list Relates 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 with Relates two concepts coming, by convention, from different schemes, and that have comparable meanings These 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 match skos:broadMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes. has narrower match skos:narrowMatch is used to state a hierarchical mapping link between two conceptual resources in different concept schemes. has related match skos:relatedMatch is used to state an associative mapping link between two conceptual resources in different concept schemes. has exact match skos: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 match skos: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. Community Community is a high-level concept that defines an online community and what it consists of. Container An area in which content Items are contained. Forum A discussion area on which Posts or entries are made. Item An Item is something which can be in a Container. Post An article or message that can be posted to a Forum. Role A Role is a function of a User within a scope of a particular Forum, Site, etc. Space A Space is a place where data resides, e.g. on a website, desktop, fileshare, etc. Site A 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. Thread A container for a series of threaded discussion Posts or Items. User A User account in an online community site. Usergroup A set of User accounts whose owners have a common purpose or interest. Can be used for access control purposes. about Specifies that this Item is about a particular resource, e.g. a Post describing a book, hotel, etc. account_of Refers to the foaf:Agent or foaf:Person who owns this sioc:User online account. administrator_of A Site that the User is an administrator of. attachment The URI of a file attached to an Item. avatar An image or depiction used to represent this User. container_of An Item that this Container contains. content The content of the Item in plain text format. creator_of A resource that the User is a creator of. Links to a previous (older) revision of this Item or Post. earlier_version email An electronic mail address of the User. email_sha1 An electronic mail address of the User, encoded using SHA1. feed A feed (e.g. RSS, Atom, etc.) pertaining to this resource (e.g. for a Forum, Site, User, etc.). follows Indicates that one User follows another User (e.g. for microblog posts or other content item updates). function_of A User who has this Role. has_administrator A User who is an administrator of this Site. has_container The Container to which this Item belongs. has_creator This is the User who made this resource. has_function A Role that this User has. has_host The Site that hosts this Forum. has_member A User who is a member of this Usergroup. has_moderator A User who is a moderator of this Forum. has_modifier A User who modified this Item. has_owner A User that this resource is owned by. has_parent A Container or Forum that this Container or Forum is a child of. has_reply Points to an Item or Post that is a reply or response to this Item or Post. has_scope A resource that this Role applies to. has_space A data Space which this resource is a part of. has_subscriber A User who is subscribed to this Container. has_usergroup Points to a Usergroup that has certain access to this Space. host_of A Forum that is hosted on this Site. id An 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_address The 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_version Links to the latest revision of this Item or Post. latest_version link A URI of a document which contains this SIOC object. links_to Links extracted from hyperlinks within a SIOC concept, e.g. Post or Site. member_of A Usergroup that this User is a member of. moderator_of A Forum that User is a moderator of. modifier_of An Item that this User has modified. name The name of a SIOC instance, e.g. a username for a User, group name for a Usergroup, etc. next_by_date Next Item or Post in a given Container sorted by date. next_version Links to the next revision of this Item or Post. note A note associated with this resource, for example, if it has been edited by a User. num_replies The number of replies that this Item, Thread, Post, etc. has. Useful for when the reply structure is absent. num_views The number of times this Item, Thread, User profile, etc. has been viewed. owner_of A resource owned by a particular User, for example, a weblog or image gallery. parent_of A child Container or Forum that this Container or Forum is a parent of. previous_by_date Previous Item or Post in a given Container sorted by date. previous_version Links to the previous revision of this Item or Post. related_to Related Posts for this Post, perhaps determined implicitly from topics or references. reply_of Links to an Item or Post which this Item or Post is a reply to. scope_of A Role that has a scope of this resource. sibling An 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_of A resource which belongs to this data Space. subscriber_of A Container that a User is subscribed to. topic A topic of interest, linking to the appropriate URI, e.g. in the Open Directory Project or of a SKOS category. usergroup_of A Space that the Usergroup has access to. Address Book Describes a collection of personal or organisational addresses. Annotation Set Describes a set of annotations, for example, those created by a particular user or related to a particular topic. Audio Channel Describes a channel for distributing audio or sound files, for example, a podcast. Bookmark Folder Describes a shared collection of bookmarks. Briefcase Describes a briefcase or file service. Event Calendar Describes a calendar of events. Image Gallery Describes an image gallery, for example, a photo album. Project Directory Describes a project directory. Resume Bank Describes a collection of resumes. Review Area Describes an area where reviews are posted. Subscription List Describes a shared set of feed subscriptions. Survey Collection Describes an area where survey data can be collected, e.g. from polls. Video Channel Describes a channel for distributing videos (moving image) files, for example, a video podcast. Wiki Describes a wiki space. Favourite Things Describes a list or a collection of one's favourite things. Offer List Describes a list of the items someone has available to offer. Playlist Describes a list of media items that have been played or can be played. Reading List Describes a list of books or other materials that have been read or are suggested for reading. Wish List Describes a list of the items someone wishes to get. Argumentative Discussion Describes a discussion area where logical arguments can take place. Chat Channel Describes a channel for chat or instant messages, for example, via IRC or IM. Mailing List Describes an electronic mailing list. Message Board Describes a message board, also known as an online bulletin board or discussion forum. Microblog Describes a microblog, i.e. a blog consisting of short text messages. Weblog Describes a weblog (blog), i.e. an online journal. Poll Describes a posted item that contains a poll or survey content. Blog Post Describes a post that is specifically made on a weblog. Board Post Describes a post that is specifically made on a message board. Comment Comment 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 Message Describes an instant message, e.g. sent via Jabber. Mail Message Describes an electronic mail message, e.g. a post sent to a mailing list. Microblog Post Describes a post that is specifically made on a microblog. Wiki Article Describes a wiki article. Answer A Post that provides an answer in reply to a Question. Best Answer A 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. Question A Post that asks a Question. Category Category is used on the object of sioc:topic to indicate that this resource is a category on a site. Tag Tag is used on the object of sioc:topic to indicate that this resource is a tag on a site. SpatialThing Anything with spatial extent, i.e. size, shape, or position. e.g. people, places, bowling balls, as well as abstract areas like cubes. Point A 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). latitude The WGS84 latitude of a SpatialThing (decimal degrees). longitude The WGS84 longitude of a SpatialThing (decimal degrees). altitude The WGS84 altitude of a SpatialThing (decimal meters above the local reference ellipsoid). lat/long A comma-separated representation of a latitude, longitude coordinate. friend of A person who shares mutual friendship with this person. acquaintance of A person having more than slight or superficial knowledge of this person but short of friendship. parent of A person who has given birth to or nurtured and raised this person. sibling of A person having one or both parents in common with this person. child of A person who was given birth to or nurtured and raised by this person. grandchild of Grandchild Of A person who is a child of any of this person's children. spouse of A person who is married to this person enemy of A person towards whom this person feels hatred, intends injury to, or opposes the interests of. antagonist of A person who opposes and contends against this person. ambivalent of A person towards whom this person has mixed feelings or emotions. lost contact with A person who was once known by this person but has subsequently become uncontactable. knows of A person who has come to be known to this person through their actions or position. would like to now A person whom this person would desire to know more closely. knows in passing A person whom this person has slight or superficial knowledge of. knows by reputation A person known by this person primarily for a particular action, position or field of endeavour. close friend of A person who shares a close mutual friendship with this person. has met A person who has met this person whether in passing or longer. works with A person who works for the same employer as this person. colleague of A person who is a member of the same profession as this person. collaborates with A person who works towards a common goal with this person. employer of A person who engages the services of this person. employed by A person for whom this person's services have been engaged. mentor of A person who serves as a trusted counselor or teacher to this person. apprentice to A person to whom this person serves as a trusted counselor or teacher. lives with A person who shares a residence with this person. neighbor of A person who lives in the same locality as this person. grandparent of A person who is the parent of any of this person's parents. life partner of A person who has made a long-term commitment to this person's. engaged to A person to whom this person is betrothed. ancestor of A person who is a descendant of this person. Descendant Of descendant of A person from whom this person is descended. participant in participant influenced by a person who has influenced this person. The object is a Tag which plays a role in the subject Tagging. associated tag testing The 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 tag testing Indicates 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 of 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? tag name The two tags are asserted as being related. This might be symmetric, but it certainly isn't transitive. related tag testing The relationship between a resource and a Tagging. Note, of course, that this allows us to tag tags and taggings themselves... tag 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'. tag name The object plays the role of the tagger in the subject Tagging. tagged by testing The subject Tagging occurred at the subject time and date. tagged on testing The object is a resource which plays a role in the subject Tagging. tagged resource testing Indicates 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".
Enabled Service Connector QueryEndPoint UpdateEndPoint DataEndpoint DefaultGraph Comments
No Fuseki (mem)1 Fuseki http://localhost:3030/db/query http://localhost:3030/db/update '' '' fuseki-server --update --port=3030 --mem /db
No Fuseki (memTDB) Fuseki http://localhost:3030/db/query http://localhost:3030/db/update '' http://example.org/myFusekiGraph fuseki-server --update --port=3030 --memTDB --set tdb:unionDefaultGraph=true /db
Yes Virtuoso opensource Virtuoso http://localhost:8890/sparql http://localhost:8890/sparql '' http://example.org/myVirtuosoGraph sudo apt-get install virtuoso-opensource
No 4store2 4store http://localhost:8088/sparql/ http://localhost:8088/update/ '' http://example.org/myFourGraph apt-get install 4store
No Sesame Custom http://localhost:8080/openrdf-sesame/repositories/test-smw http://localhost:8080/openrdf-sesame/repositories/test-smw/statements '' `test-smw` is specifed as native in-memory store
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 ================================================ '*ini*', vhost=>'*ini*', lpath=>'/OntoWiki' ); DB.DBA.VHOST_DEFINE ( lhost=>'*ini*', vhost=>'*ini*', lpath=>'/OntoWiki', ppath=>'/vad/vsp/ontowiki/', is_dav=>0, def_page=>'index.php', vsp_user=>'dba', ses_vars=>0, opts=>vector ('browse_sheet', '', 'url_rewrite', 'http_rule_list_2'), is_default_host=>0 ); DB.DBA.URLREWRITE_CREATE_RULELIST ( 'http_rule_list_2', 1, vector ('http_rule_4', 'http_rule_5')); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'http_rule_4', 1, '/OntoWiki/(.*)$', vector (), 0, '/OntoWiki/index.php', vector (), NULL, NULL, 0, 0, '' ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'http_rule_5', 1, '/OntoWiki/(extensions|application|libraries)(.*).(js|ico|gif|jpg|png|css|php|swf)(.*)$', vector ('par_1', 'par_2', 'par_3', 'par_4'), 4, '/OntoWiki/%s%s.%s%s', vector ('par_1', 'par_2', 'par_3', 'par_4'), NULL, NULL, 0, 0, '' ); ]]> ================================================ FILE: application/scripts/vad/ow_vad_sticker_template.xml_not_working ================================================ '*ini*', vhost=>'*ini*', lpath=>'/OntoWiki' ); DB.DBA.VHOST_DEFINE ( lhost=>'*ini*', vhost=>'*ini*', lpath=>'/OntoWiki', ppath=>'/vad/vsp/ontowiki/', is_dav=>0, def_page=>'index.php', vsp_user=>'OntoWikiAdmin', ses_vars=>0, opts=>vector ('browse_sheet', '', 'url_rewrite', 'http_rule_list_2'), is_default_host=>0 ); DB.DBA.URLREWRITE_CREATE_RULELIST ( 'http_rule_list_2', 1, vector ('http_rule_4', 'http_rule_5')); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'http_rule_4', 1, '/OntoWiki/(.*)$', vector (), 0, '/OntoWiki/index.php', vector (), NULL, NULL, 0, 0, '' ); DB.DBA.URLREWRITE_CREATE_REGEX_RULE ( 'http_rule_5', 1, '/OntoWiki/(extensions|application|libraries)(.*).(js|ico|gif|jpg|png|css|php|swf)(.*)$', vector ('par_1', 'par_2', 'par_3', 'par_4'), 4, '/OntoWiki/%s%s.%s%s', vector ('par_1', 'par_2', 'par_3', 'par_4'), NULL, NULL, 0, 0, '' ); ]]> ================================================ FILE: application/scripts/vad/prepare.sh ================================================ #!/bin/bash VIRTTMP=/tmp/virtuoso STICKERBEGIN=ow_vad_sticker_template.xml STICKER=ow_vad_sticker.xml RESULTFILE=ontowiki_fs.vad ISQLFILE=DB.PACK.VAD.isql VIRTUOSO_T="/opt/vos-6.1.2/bin/virtuoso-t -c vad.ini -f" CURRENT=$PWD #do not change this below: BUILDPATH=/tmp/ontowiki echo "DB.DBA.VAD_PACK ('"$PWD/$STICKER"' , '' , '"$PWD"/"$RESULTFILE"' ); shutdown; " > $ISQLFILE echo "deleting "$BUILDPATH rm -r $BUILDPATH echo "deleting "$VIRTTMP rm -r $VIRTTMP echo "checking out ontowiki" hg clone https://ontowiki.googlecode.com/hg/ $BUILDPATH cd $BUILDPATH make zend cd $CURRENT echo "setting options in "$BUILDPATH/config.ini":" echo "[private] store.backend = virtuoso store.virtuoso.dsn = Local Virtuoso store.virtuoso.username = dba store.virtuoso.password = dba languages.locale = \"en\" debug = on cache.query.enable = 0 " > $BUILDPATH/config.ini echo "*****************verify:" cat $BUILDPATH/config.ini echo "*****************" mkdir -v $BUILDPATH/logs chmod 777 $BUILDPATH/logs mkdir -v $BUILDPATH/cache chmod 777 $BUILDPATH/cache echo "vad sticker is assembled from "$STICKERBEGIN cat $STICKERBEGIN >$STICKER find $BUILDPATH -name ".hg" | xargs rm -r cd /tmp for onefile in `find ontowiki -type f | grep -v ' '` do echo "" >> $CURRENT/$STICKER done cd $CURRENT echo "" >> $STICKER echo "sticker created at "$STICKER echo "copying ontowiki where virtuoso expects it" mkdir $VIRTTMP mkdir $VIRTTMP/vad mkdir $VIRTTMP/vad/vsp cp -r $BUILDPATH $VIRTTMP/vad/vsp cp vad.ini $VIRTTMP cd $VIRTTMP #Error 42VAD: [Virtuoso Driver][Virtuoso Server]Inexistent file resource (./vad/vsp//tmp/ontowiki/favicon.png) $VIRTUOSO_T cd $CURRENT ================================================ FILE: application/scripts/vad/vad.ini ================================================ ; ; virtuoso.ini ; ; Configuration file for the OpenLink Virtuoso VDBMS Server ; ; To learn more about this product, or any other product in our ; portfolio, please check out our web site at: ; ; http://virtuoso.openlinksw.com/ ; ; or contact us at: ; ; general.information@openlinksw.com ; ; If you have any technical questions, please contact our support ; staff at: ; ; technical.support@openlinksw.com ; ; ; Database setup [Database] DatabaseFile = /tmp/virtuoso/virtuoso.db ErrorLogFile = /tmp/virtuoso/virtuoso.log LockFile = /tmp/virtuoso/virtuoso.lck TransactionFile = /tmp/virtuoso/virtuoso.trx xa_persistent_file = /tmp/virtuoso/virtuoso.pxa ErrorLogLevel = 7 FileExtend = 200 MaxCheckpointRemap = 2000 Striping = 0 TempStorage = TempDatabase [TempDatabase] DatabaseFile = /tmp/virtuoso/virtuoso-temp.db TransactionFile = /tmp/virtuoso/virtuoso-temp.trx MaxCheckpointRemap = 2000 Striping = 0 ; ; Server parameters ; [Parameters] ServerPort = 9999 LiteMode = 0 DisableUnixSocket = 1 DisableTcpSocket = 0 ;SSLServerPort = 2111 ;SSLCertificate = cert.pem ;SSLPrivateKey = pk.pem ;X509ClientVerify = 0 ;X509ClientVerifyDepth = 0 ;X509ClientVerifyCAFile = ca.pem ServerThreads = 20 CheckpointInterval = 60 O_DIRECT = 0 NumberOfBuffers = 20000 MaxDirtyBuffers = 12000 CaseMode = 2 MaxStaticCursorRows = 5000 CheckpointAuditTrail = 0 AllowOSCalls = 0 SchedulerInterval = 10 DirsAllowed = .,/, /tmp , /tmp/virtuoso ThreadCleanupInterval = 0 ThreadThreshold = 10 ResourcesCleanupInterval = 0 FreeTextBatchSize = 100000 SingleCPU = 0 VADInstallDir = /tmp/virtuoso/share/virtuoso/vad/ PrefixResultNames = 0 RdfFreeTextRulesSize = 100 IndexTreeMaps = 256 [HTTPServer] ServerPort = 9998 ServerRoot = /tmp/virtuoso/var/lib/virtuoso/vsp ServerThreads = 20 DavRoot = DAV EnabledDavVSP = 0 HTTPProxyEnabled = 0 TempASPXDir = 0 DefaultMailServer = localhost:25 ServerThreads = 10 MaxKeepAlives = 10 KeepAliveTimeout = 10 MaxCachedProxyConnections = 10 ProxyConnectionCacheTimeout = 15 HTTPThreadSize = 280000 HttpPrintWarningsInOutput = 0 Charset = UTF-8 HTTPLogFile = /tmp/virtuoso/tmp/httplog20102010.log [AutoRepair] BadParentLinks = 0 [Client] SQL_PREFETCH_ROWS = 100 SQL_PREFETCH_BYTES = 16000 SQL_QUERY_TIMEOUT = 0 SQL_TXN_TIMEOUT = 0 ;SQL_NO_CHAR_C_ESCAPE = 1 ;SQL_UTF8_EXECS = 0 ;SQL_NO_SYSTEM_TABLES = 0 ;SQL_BINARY_TIMESTAMP = 1 ;SQL_ENCRYPTION_ON_PASSWORD = -1 [VDB] ArrayOptimization = 0 NumArrayParameters = 10 VDBDisconnectTimeout = 1000 KeepConnectionOnFixedThread = 0 [Replication] ServerName = db-UL ServerEnable = 1 QueueMax = 50000 ; ; Striping setup ; ; These parameters have only effect when Striping is set to 1 in the ; [Database] section, in which case the DatabaseFile parameter is ignored. ; ; With striping, the database is spawned across multiple segments ; where each segment can have multiple stripes. ; ; Format of the lines below: ; Segment = , [, .. ] ; ; must be ordered from 1 up. ; ; The is the total size of the segment which is equally divided ; across all stripes forming the segment. Its specification can be in ; gigabytes (g), megabytes (m), kilobytes (k) or in database blocks ; (b, the default) ; ; Note that the segment size must be a multiple of the database page size ; which is currently 8k. Also, the segment size must be divisible by the ; number of stripe files forming the segment. ; ; The example below creates a 200 meg database striped on two segments ; with two stripes of 50 meg and one of 100 meg. ; ; You can always add more segments to the configuration, but once ; added, do not change the setup. ; [Striping] Segment1 = 100M, db-seg1-1.db, db-seg1-2.db Segment2 = 100M, db-seg2-1.db ;... ;[TempStriping] ;Segment1 = 100M, db-seg1-1.db, db-seg1-2.db ;Segment2 = 100M, db-seg2-1.db ;... ;[Ucms] ;UcmPath = ;Ucm1 = ;Ucm2 = ;... [Zero Config] ServerName = virtuoso (UL) ;ServerDSN = ZDSN ;SSLServerName = ;SSLServerDSN = [Mono] ;MONO_TRACE = Off ;MONO_PATH = ;MONO_ROOT = ;MONO_CFG_DIR = ;virtclr.dll = [URIQA] DynamicLocal = 1 DefaultHost = localhost:8890 [SPARQL] ;ExternalQuerySource = 1 ;ExternalXsltSource = 1 ;DefaultGraph = http://localhost:8890/dataspace ;ImmutableGraphs = http://localhost:8890/dataspace ResultSetMaxRows = 10000 MaxQueryCostEstimationTime = 400 ; in seconds MaxQueryExecutionTime = 60 ; in seconds DefaultQuery = select distinct ?Concept where {[] a ?Concept} DeferInferenceRulesInit = 1 ; controls inference rules loading ;PingService = http://rpc.pingthesemanticweb.com/ [Plugins] LoadPath = /tmp/virtuoso/lib/virtuoso/hosting Load1 = plain, wikiv Load2 = plain, mediawiki Load3 = plain, creolewiki Load4 = plain, im ;Load5 = plain, wbxml2 ;Load6 = plain, hslookup Load7 = attach, libphp5.so Load8 = Hosting, hosting_php.so ;Load9 = Hosting,hosting_perl.so ;Load10 = Hosting,hosting_python.so ;Load11 = Hosting,hosting_ruby.so ;Load12 = msdtc,msdtc_sample ================================================ FILE: application/shell.worker.client.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; } /** * Capsuled main script returning initializes application object * @return Zend_Application */ 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(__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; return false; } // 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) { echo 'Fatal Error: Could not load the OntoWiki Application Framework classes.' . PHP_EOL; echo 'Your installation directory seems to be screwed.' . PHP_EOL; return false; } /* check/include Erfurt_App */ try { // use include, so we can catch it with the error handler require_once 'Erfurt/App.php'; } catch (Exception $e) { echo 'Fatal Error: Could not load the Erfurt Framework classes.' . PHP_EOL; echo 'Maybe you should install it with apt-get or with "make deploy"?' . PHP_EOL; return false; } // restore old error handler restore_error_handler(); // bootstrap try { $application->bootstrap(); } catch (Exception $e) { echo 'Error on bootstrapping application: ' . $e->getMessage() . PHP_EOL; return false; } return $application; } $application = initApp(); if ($application === false) { return 1; } $ontowiki = OntoWiki::getInstance(); echo $ontowiki->config->version->label . ' ' . $ontowiki->config->version->number . PHP_EOL; $timeStart = microtime(true); /* -- EXAMPLE JOB CALL -------------------------------------------------- */ $ontowiki->callJob("test", array('repeat' => 10)); // initialize the cron job $ontowiki->callJob("cron"); //$workload = array( //'receiver' => "", //'sender' => "me@example.tld", //'subject' => "Test @ ".time(), //'body' => "This is just a test..." //); //if(empty($workload['receiver'])) //die("Please set receiver to run this example!"); //$client->call( "testMail", $workload ); /* -- END OF EXAMPLE -------------------------------------------------- */ echo "done in " . round((microtime(true) - $timeStart) * 1000, 2) . "ms" . PHP_EOL; ================================================ FILE: application/shell.worker.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(__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; return false; } // 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) { echo 'Fatal Error: Could not load the OntoWiki Application Framework classes.' . PHP_EOL; echo 'Your installation directory seems to be screwed.' . PHP_EOL; return false; } /* check/include Erfurt_App */ try { // use include, so we can catch it with the error handler require_once 'Erfurt/App.php'; } catch (Exception $e) { echo 'Fatal Error: Could not load the Erfurt Framework classes.' . PHP_EOL; echo 'Maybe you should install it with apt-get or with "make deploy"?' . PHP_EOL; return false; } // restore old error handler restore_error_handler(); // bootstrap try { $application->bootstrap(); } catch (Exception $e) { echo 'Error on bootstrapping application: ' . $e->getMessage() . PHP_EOL; return false; } return $application; } $application = initApp(); if ($application === false) { return 1; } $bootstrap = $application->getBootstrap(); $ontoWiki = OntoWiki::getInstance(); $extManager = $ontoWiki->extensionManager; $extensions = $extManager->getExtensions(); echo $ontoWiki->config->version->label . ' ' . $ontoWiki->config->version->number . PHP_EOL; // create a worker registry $workerRegistry = Erfurt_Worker_Registry::getInstance(); // trigger event to let extensions add their jobs $event = new Erfurt_Event('onAnnounceWorker'); $event->bootstrap = $bootstrap; $event->registry = $workerRegistry; $event->trigger(); if (!count($workerRegistry->getJobs())) { echo 'No jobs registered - nothing to do or wait for.' . PHP_EOL; return; } // register jobs manually // key name, class file, class name, config // test job $workerRegistry->registerJob( 'test', 'libraries/Erfurt/library/Erfurt/Worker/TestJob.php', 'Erfurt_Worker_TestJob', array() ); // cron job $workerRegistry->registerJob( 'cron', 'application/classes/OntoWiki/Jobs/Cron.php', 'OntoWiki_Jobs_Cron', array() ); // create a new worker backend with filled worker registry $worker = new Erfurt_Worker_Backend($workerRegistry); // set worker and Gearman worker to listen mode and wait $worker->listen(); ================================================ FILE: application/tests/Bootstrap.php ================================================ * @link http://code.google.com/p/ontowiki/ */ /** * Ontowiki_Sniffs_Classes_ClassFilePathSniff. * * Tests that the filepath correspond to the classname for php Files in * the application/classes Folder * * @category PHP * @package PHP_CodeSniffer * @author Lars Eidam * @link http://code.google.com/p/ontowiki/ */ class Ontowiki_Sniffs_Classes_ClassFilePathSniff implements PHP_CodeSniffer_Sniff { /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array(T_CLASS); } //end register() /** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $decName = $phpcsFile->findNext(T_STRING, $stackPtr); $fullPath = $phpcsFile->getFilename(); $longFileName = basename($fullPath); $fileName = substr($longFileName, 0, strrpos($longFileName, '.')); // if the file is under the application/classes folder the class has the path in the name // application/classes/Ontowiki/Utils/TestClass.php -> Classname=Ontowiki_Utils_TestClass if (stristr($fullPath, 'application/classes') !== false) { $partedPath = substr($fullPath, strrpos($fullPath, 'classes'), strlen($fullPath)); $partedPath = substr($partedPath, 0, strrpos($partedPath, '.')); $classNameArray = explode("_", $tokens[$decName]['content']); $filepathArray = explode("/", $partedPath); if (1 == count($filepathArray)) { $filepathArray = explode("\\", $partedPath); } $notFound = true; foreach ($classNameArray as $index => $classNamePart) { if ($classNamePart != $filepathArray[$index + 1]) { $notFound = false; break; } } array_shift($filepathArray); if (false === $notFound) { $error = '%s name doesn\'t match filepath; expected "%s %s"'; $data = array( ucfirst($tokens[$stackPtr]['content']), $tokens[$stackPtr]['content'], implode('_', $filepathArray), ); $phpcsFile->addError($error, $stackPtr, 'NoMatch', $data); } } } //end process() } //end class ?> ================================================ FILE: application/tests/CodeSniffer/Standards/Ontowiki/Sniffs/Commenting/FileCommentSniff.php ================================================ * @copyright 2015 Stefano Kowalke * @license http://www.gnu.org/copyleft/gpl.html GNU Public License * @link https://github.com/typo3-ci/TYPO3SniffPool */ class Ontowiki_Sniffs_Commenting_FileCommentSniff implements PHP_CodeSniffer_Sniff { /** * The file comment in TYPO3 CMS must be the copyright notice. * * @var array */ protected $_copyright = array( 1 => "/**\n", 2 => " * This file is part of the {@link http://ontowiki.net OntoWiki} project.\n", 3 => " *\n", 4 => "", 5 => " * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)\n", 6 => " */", ); /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array(T_OPEN_TAG); }//end register() /** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token * in the stack passed in $tokens. * * @return int */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Find the next non whitespace token. $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($stackPtr + 1), null, true); if ($commentStart === false) { $phpcsFile->addError('Not file level comment given', $commentStart, 'NoFileLevelCommentFound'); return; } $noGit = true; if (count($tokens) > ($commentStart + 14)) { preg_match("/ ([0-9]{4})(-[0-9]{4})?/", $tokens[$commentStart + 15]['content'], $nonGitYear); } //test if a git exists to get the years from 'git log' exec('([ -d .git ] && echo .git) || git rev-parse --git-dir 2> /dev/null', $gitTest); if (!empty($gitTest)) { $output = array(); exec('git ls-files --error-unmatch ' . $phpcsFile->getFilename() . ' 2> /dev/null', $output, $returnValue); if ($returnValue == 0) { $noGit = false; } } if (!$noGit) { //test if a git entry exists to get the years from 'git log' exec('git log --reverse ' . $phpcsFile->getFilename() . ' | head -4', $outputCreationYear); preg_match("/( )[0-9]{4}( )/", $outputCreationYear[2], $gitOldYearArray); if (empty($gitOldYearArray) && count($outputCreationYear) > 3) { preg_match("/( )[0-9]{4}( )/", $outputCreationYear[3], $gitOldYearArray); } $gitYearOld = str_replace(' ', '', $gitOldYearArray[0]); if (isset($nonGitYear) && isset($nonGitYear[1]) && $gitYearOld > $nonGitYear[1]) { $gitYearOld = $nonGitYear[1]; } exec('git log -1 ' . $phpcsFile->getFilename(), $outputLastEditYear); preg_match("/( )[0-9]{4}( )/", $outputLastEditYear[2], $gitNewYearArray); if (empty($gitNewYearArray) && count($outputLastEditYear) > 3) { preg_match("/( )[0-9]{4}( )/", $outputLastEditYear[3], $gitNewYearArray); } $gitYearNew = str_replace(' ', '', $gitNewYearArray[0]); if (strcmp($gitYearOld, $gitYearNew) != 0) { $gitYearOld .= '-'; $gitYearOld .= $gitYearNew; } $year = " * @copyright Copyright (c) " . $gitYearOld . ", {@link http://aksw.org AKSW}\n"; $this->_copyright[4] = $year; } else { //tests if the file has no year/wrong editing and the year can't be found if (!empty($nonGitYear)) { $year = str_replace(' ', '', $nonGitYear[0]); $copyright = " * @copyright Copyright (c) " . $year . ", {@link http://aksw.org AKSW}\n"; $this->_copyright[4] = $copyright; } } $tokenizer = new PHP_CodeSniffer_Tokenizers_Comment(); $expectedString = implode($this->_copyright); $expectedTokens = $tokenizer->tokenizeString($expectedString, PHP_EOL, 0); // Allow namespace statements at the top of the file. if ($tokens[$commentStart]['code'] === T_NAMESPACE) { $semicolon = $phpcsFile->findNext(T_SEMICOLON, ($commentStart + 1)); $commentStart = $phpcsFile->findNext(T_WHITESPACE, ($semicolon + 1), null, true); } if ($tokens[$commentStart]['code'] !== T_DOC_COMMENT_OPEN_TAG) { $fix = $phpcsFile->addFixableError( 'Copyright notice must start with /**; but /* was found!', $commentStart, 'WrongStyle' ); if ($fix === true) { $phpcsFile->fixer->replaceToken($commentStart, "/**"); } return; } $commentEnd = ($phpcsFile->findNext(T_WHITESPACE, ($commentStart + 1)) - 1); if ($tokens[$commentStart]['code'] !== T_DOC_COMMENT_OPEN_TAG) { $phpcsFile->addError('Copyright notice missing', $commentStart, 'NoCopyrightFound'); return; } $commentEndLine = $tokens[$commentEnd]['line']; $commentStartLine = $tokens[$commentStart]['line']; if ((($commentEndLine - $commentStartLine) + 1) < count($this->_copyright)) { $phpcsFile->addError( 'Copyright notice too short', $commentStart, 'CommentTooShort' ); return; } else if ((($commentEndLine - $commentStartLine) + 1) > count($this->_copyright)) { $phpcsFile->addError( 'Copyright notice too long', $commentStart, 'CommentTooLong' ); return; } $j = 0; for ($i = $commentStart; $i <= $commentEnd; $i++) { if ($tokens[$i]['content'] !== $expectedTokens[$j]["content"]) { $error = 'Found wrong part of copyright notice. Expected "%s", but found "%s"'; $data = array( $expectedTokens[$j]["content"], $tokens[$i]['content'], ); $fix = $phpcsFile->addFixableError($error, $i, 'WrongText', $data); if ($fix === true) { $phpcsFile->fixer->replaceToken($i, $expectedTokens[$j]["content"]); } } $j++; } }//end process() }//end class ================================================ FILE: application/tests/CodeSniffer/Standards/Ontowiki/Sniffs/Functions/ForbiddenFunctionsSniff.php ================================================ * @link http://code.google.com/p/ontowiki/ */ /** * Ontowiki_Sniffs_Function_ForbiddenFunctionsSniff. * Check for functions, they are not allowed. * * @category PHP * @package PHP_CodeSniffer_Sniff * @author Lars Eidam * @link http://code.google.com/p/ontowiki/ */ class Ontowiki_Sniffs_Functions_ForbiddenFunctionsSniff extends Generic_Sniffs_PHP_ForbiddenFunctionsSniff { /** * A list of forbidden functions with their alternatives. * * @var array(string => string|null) */ public $forbiddenFunctions = array( 'var_dump' => null, 'error_log' => null, 'exit' => 'return', 'die' => 'return' ); /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { $tokens = parent::register(); $tokens[] = T_EXIT; return $tokens; } //end register() } //end class ?> ================================================ FILE: application/tests/CodeSniffer/Standards/Ontowiki/Sniffs/Functions/FunctionCallArgumentSpacingSniff.php ================================================ * @author Marc McIntyre * @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600) * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence * @link http://pear.php.net/package/PHP_CodeSniffer */ /** * Generic_Sniffs_Functions_FunctionCallArgumentSpacingSniff. * * Checks that calls to methods and functions are spaced correctly. * * @category PHP * @package PHP_CodeSniffer * @author Greg Sherwood * @author Marc McIntyre * @copyright 2006-2011 Squiz Pty Ltd (ABN 77 084 670 600) * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence * @version Release: 1.3.2 * @link http://pear.php.net/package/PHP_CodeSniffer */ /** * Little changes for Ontowiki requirements: * After commas in function calls must at least one space but it can also be * more to be able to align the code. * * @author Lars Eidam */ class Ontowiki_Sniffs_Functions_FunctionCallArgumentSpacingSniff implements PHP_CodeSniffer_Sniff { /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array(T_STRING); } //end register() /** * Processes this test, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); // Skip tokens that are the names of functions or classes // within their definitions. For example: // function myFunction... // "myFunction" is T_STRING but we should skip because it is not a // function or method *call*. $functionName = $stackPtr; $ignoreTokens = PHP_CodeSniffer_Tokens::$emptyTokens; $ignoreTokens[] = T_BITWISE_AND; $functionKeyword = $phpcsFile->findPrevious($ignoreTokens, ($stackPtr - 1), null, true); if ($tokens[$functionKeyword]['code'] === T_FUNCTION || $tokens[$functionKeyword]['code'] === T_CLASS ) { return; } // If the next non-whitespace token after the function or method call // is not an opening parenthesis then it cant really be a *call*. $openBracket = $phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ($functionName + 1), null, true ); if ($tokens[$openBracket]['code'] !== T_OPEN_PARENTHESIS) { return; } $closeBracket = $tokens[$openBracket]['parenthesis_closer']; $nextSeperator = $openBracket; while (($nextSeperator = $phpcsFile->findNext( array(T_COMMA, T_VARIABLE), ($nextSeperator + 1), $closeBracket )) !== false) { // Make sure the comma or variable belongs directly to this function call, // and is not inside a nested function call or array. $brackets = $tokens[$nextSeperator]['nested_parenthesis']; $lastBracket = array_pop($brackets); if ($lastBracket !== $closeBracket) { continue; } if ($tokens[$nextSeperator]['code'] === T_COMMA) { if ($tokens[($nextSeperator - 1)]['code'] === T_WHITESPACE) { $error = 'Space found before comma in function call'; $phpcsFile->addError($error, $stackPtr, 'SpaceBeforeComma'); } if ($tokens[($nextSeperator + 1)]['code'] !== T_WHITESPACE) { $error = 'No space found after comma in function call'; $phpcsFile->addError($error, $stackPtr, 'NoSpaceAfterComma'); } } else { // Token is a variable. $nextToken = $phpcsFile->findNext( PHP_CodeSniffer_Tokens::$emptyTokens, ($nextSeperator + 1), $closeBracket, true ); if ($nextToken !== false) { if ($tokens[$nextToken]['code'] === T_EQUAL) { if (($tokens[($nextToken - 1)]['code']) !== T_WHITESPACE) { $error = 'Expected 1 space before = sign of default value'; $phpcsFile->addError($error, $stackPtr, 'NoSpaceBeforeEquals'); } if ($tokens[($nextToken + 1)]['code'] !== T_WHITESPACE) { $error = 'Expected 1 space after = sign of default value'; $phpcsFile->addError($error, $stackPtr, 'NoSpaceAfterEquals'); } } } } //end if } //end while } //end process() } //end class ?> ================================================ FILE: application/tests/CodeSniffer/Standards/Ontowiki/Sniffs/PHP/GetRequestDataSniff.php ================================================ * @link http://code.google.com/p/ontowiki/ */ /** * Ontowiki_Sniffs_PHP_GetRequestDataSniff. * Ensures that getRequestData() is used to access super globals. * * @category PHP * @package PHP_CodeSniffer * @author Lars Eidam * @link http://code.google.com/p/ontowiki/ */ class Ontowiki_Sniffs_PHP_GetRequestDataSniff implements PHP_CodeSniffer_Sniff { /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array(T_VARIABLE); } //end register() /** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in * the stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { $tokens = $phpcsFile->getTokens(); $varName = $tokens[$stackPtr]['content']; if ($varName !== '$_REQUEST' && $varName !== '$_GET' && $varName !== '$_POST' && $varName !== '$_FILES' ) { return; } $type = 'SuperglobalAccessed'; $error = 'The %s super global must not be accessed directly;' . 'use Zend_Controller_Front::getInstance()->getRequest() instead'; $data = array($varName); $phpcsFile->addError($error, $stackPtr, $type, $data); } //end process() } //end class ?> ================================================ FILE: application/tests/CodeSniffer/Standards/Ontowiki/ruleset.xml ================================================ Ontowiki's additiona sniffs for the coding standard. ================================================ FILE: application/tests/config.ini.dist ================================================ [private] ;;----------------------------------------------------------------------------;; ;; Database Connection Settings ;; ;;----------------------------------------------------------------------------;; store.backend = zenddb ; zenddb, virtuoso, multi store.zenddb.dbname = ow_TEST ; needs to end with _TEST store.zenddb.username = php store.zenddb.password = php store.zenddb.dbtype = mysql ; mysql store.zenddb.host = localhost ; default is localhost store.virtuoso.dsn = VOS_TEST ; needs to end with _TEST store.virtuoso.username = dba store.virtuoso.password = dba ================================================ FILE: application/tests/config.ini.dist.travis ================================================ [private] ;;----------------------------------------------------------------------------;; ;; Database Connection Settings ;; ;;----------------------------------------------------------------------------;; store.backend = zenddb ; zenddb, virtuoso, multi store.zenddb.dbname = ontowiki_TEST ; needs to end with _TEST store.zenddb.username = travis store.zenddb.password = store.zenddb.dbtype = mysql ; mysql store.zenddb.host = localhost ; default is localhost store.virtuoso.dsn = VOS_TEST ; needs to end with _TEST store.virtuoso.username = dba store.virtuoso.password = dba ================================================ FILE: application/tests/integration/OntoWiki/Extension/ManagerIntegrationTest.php ================================================ */ class ManagerIntegrationTest extends Erfurt_TestCase { protected $_resourcesDirectory = null; protected $_bootstrap = null; protected function setUp() { $this->_resourcesDirectory = realpath(dirname(__FILE__)) . '/_files/'; $this->markTestNeedsDatabase(); $this->_bootstrap = new Zend_Application( 'integration_testing', ONTOWIKI_ROOT . 'application/config/application.ini' ); // bootstrap try { $this->_bootstrap->bootstrap(); } catch (Exception $e) { echo 'Error on bootstrapping application: '; echo $e->getMessage(); return; } $this->authenticateDbUser(); } /** * @medium */ public function testScan() { Erfurt_App::getInstance(false)->getCache()->clean(); // clear cache, since otherwise the extension manager may have the real extensions loaded if (function_exists('apc_clear_cache')) { apc_clear_cache('user'); } $em = new OntoWiki_Extension_Manager($this->_resourcesDirectory, CACHE_PATH . 'extensions_test.json'); $ex = $em->getExtensions(); $this->assertCount(2, $ex); $this->assertArrayHasKey('test1', $ex); $this->assertArrayHasKey('test2', $ex); //test local ini $this->assertFalse((bool)$ex['test2']->private->sub->b); } } ================================================ FILE: application/tests/integration/OntoWiki/Extension/_files/test1/MoreModule.php ================================================ getMenu('application'); } public function getContents() { return ''; } public function allowCaching() { // no caching return false; } } ================================================ FILE: application/tests/integration/OntoWiki/Extension/_files/test1/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :test . :test a doap:Project ; doap:name "test1" ; owconfig:privateNamespace ; owconfig:enabled "true"^^xsd:boolean ; rdfs:label "Some Extension 1" ; doap:description "provides a login module and a recover action." ; owconfig:authorLabel "AKSW" ; doap:maintainer ; owconfig:templates "templates" ; owconfig:languages "languages" ; owconfig:hasModule :Test ; owconfig:hasModule :More ; doap:release :v1-0 . :Test a owconfig:Module ; rdfs:label "Test Module" ; owconfig:caching "true"^^xsd:boolean ; owconfig:priority "30" ; owconfig:context "main.sidewindows" ; :prop "val2" . :More a owconfig:Module ; rdfs:label "More Module" ; owconfig:caching "false"^^xsd:boolean ; owconfig:priority "40" ; owconfig:context "main.sidewindows" ; :prop "val1" . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: application/tests/integration/OntoWiki/Extension/_files/test2/Test2Plugin.php ================================================ . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :test2 . :test2 a doap:Project ; doap:name "test2" ; owconfig:privateNamespace ; owconfig:enabled "true"^^xsd:boolean ; rdfs:label "Some Extension 2" ; doap:description "provides a login module and a recover action." ; owconfig:authorLabel "AKSW" ; doap:maintainer ; owconfig:templates "templates" ; owconfig:languages "languages" . :test2 owconfig:config [ a owconfig:Config; owconfig:id "sub"; :b "true"^^xsd:boolean ] ; doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: application/tests/integration/OntoWiki/Extension/_files/test2.ini ================================================ [private] sub.b = false ================================================ FILE: application/tests/integration/OntoWiki/Model/InstancesIntegrationTest.php ================================================ */ class OntoWiki_Model_InstancesIntegrationTest extends Erfurt_TestCase { /** * * @var OntoWiki_Model_Instances */ protected $_instances = null; protected $_modelUri = 'http://example.org/test/'; /** * * @var Erfurt_Store */ protected $_store = null; public function setUp() { $this->markTestNeedsDatabase(); $this->authenticateDbUser(); $this->_store = $this->getStore(); //create model $model = $this->_store->getNewModel($this->_modelUri, '', Erfurt_Store::MODEL_TYPE_OWL, false); $this->_instances = new OntoWiki_Model_Instances( $this->_store, new Erfurt_Rdf_Model($this->_modelUri, null, $this->_store) ); $this->addTestData(); $this->_instances->getResources(); parent::setUp(); } private $_class = 'http://model.org/model#className1'; public function addTestData() { $this->authenticateDbUser(); $turtleString = ' a <' . $this->_class . '> ; "instance1"; "val1", "val2" . a <' . $this->_class . '> ; "instance2" ; "val3" .'; $this->_store->importRdf( $this->_modelUri, $turtleString, 'turtle', Erfurt_Syntax_RdfParser::LOCATOR_DATASTRING, false ); } public function getStore() { return Erfurt_App::getInstance()->getStore(); } /** * @medium */ public function testResources() { //two instances and a triple for the graph $this->assertCount(3, $this->_instances->getResources()); } /** * @medium */ public function testTypeFilter() { $id = $this->_instances->addTypeFilter($this->_class); $this->assertCount(2, $this->_instances->getResources()); $this->_instances->removeFilter($id); $this->_instances->addTypeFilter('http://other'); $this->assertEmpty($this->_instances->getResources()); } /** * @medium */ public function testGetValues() { $v = $this->_instances->getValues(); $this->assertCount(3, $v); $this->assertArrayHasKey('http://model.org/model#i1', $v); $this->assertArrayHasKey('http://model.org/model#i2', $v); // the __TYPE $this->assertCount(1, $v['http://model.org/model#i1']); $this->assertArrayHasKey('__TYPE', $v['http://model.org/model#i1']); $this->assertContains($this->_class, self::_onlyValues($v['http://model.org/model#i1']['__TYPE'])); } /** * @medium */ public function testAddShownProperties() { //add properties $this->_instances->addShownProperty('http://model.org/prop'); $v = $this->_instances->getValues(); //count values $this->assertCount(2, $v['http://model.org/model#i1']); //test variable creation $this->assertArrayHasKey('prop', $v['http://model.org/model#i1']); //test values $this->assertCount(2, $v['http://model.org/model#i1']['prop']); $this->assertContains("val1", self::_onlyValues($v['http://model.org/model#i1']['prop'])); $this->assertContains("val2", self::_onlyValues($v['http://model.org/model#i1']['prop'])); //another one $this->_instances->addShownProperty('http://www.w3.org/2000/01/rdf-schema#label'); $v = $this->_instances->getValues(); $this->assertCount(3, $v['http://model.org/model#i1']); $this->assertArrayHasKey('label', $v['http://model.org/model#i1']); } /** * @medium */ public function testGetProperties() { $p = $this->_instances->getAllProperties(); $this->assertCount(3, $p); $ovp = self::_onlyValues($p); $this->assertContains("http://www.w3.org/1999/02/22-rdf-syntax-ns#type", $ovp); $this->assertContains("http://model.org/prop", $ovp); $this->assertContains("http://www.w3.org/2000/01/rdf-schema#label", $ovp); } /** * @medium */ public function testGetPossibleValues() { $v = $this->_instances->getPossibleValues("http://model.org/prop"); $this->assertCount(3, $v); $ovv = self::_onlyValues($v); $this->assertContains("val1", $ovv); $this->assertContains("val2", $ovv); $this->assertContains("val3", $ovv); } /** * @medium */ public function testAddFilter() { $id = $this->_instances->addFilter("http://model.org/prop", false, 'prop', 'equals', 'val1', null, 'literal'); $this->assertCount(1, $this->_instances->getResources()); $this->_instances->removeFilter($id); $this->assertCount(3, $this->_instances->getResources()); } /** * @medium */ public function testLimitOffset() { $this->_instances->orderByUri(); $this->_instances->addTypeFilter($this->_class); $this->assertCount(2, $this->_instances->getResources()); $this->_instances->setLimit(1); $this->assertCount(1, $this->_instances->getResources()); $this->_instances->setLimit(0); $this->assertCount(2, $this->_instances->getResources()); $this->_instances->setOffset(1); $this->assertCount(1, $this->_instances->getResources()); } /** * @medium */ public function testOrderProperty() { $this->_instances->addTypeFilter($this->_class); $this->assertCount(2, $this->_instances->getResources()); $this->_instances->setOrderProperty("http://model.org/prop", true); $r = $this->_instances->getResources(); $this->assertEquals($r[0]['uri'], 'http://model.org/model#i1'); $this->_instances->setOrderProperty("http://model.org/prop", false); $r = $this->_instances->getResources(); $this->assertEquals($r[0]['uri'], 'http://model.org/model#i2'); } /** * @medium */ public function testOrderURI() { $this->_instances->addTypeFilter($this->_class); $this->assertCount(2, $this->_instances->getResources()); $this->_instances->orderByUri(true); $r = $this->_instances->getResources(); $this->assertEquals($r[0]['uri'], 'http://model.org/model#i1'); $this->_instances->orderByUri(false); $r = $this->_instances->getResources(); $this->assertEquals($r[0]['uri'], 'http://model.org/model#i2'); } /** * */ public function testShownPropertiesAddTitles() { //add $r = $this->_instances->addShownProperty("http://abc"); //test chaining $this->assertSame($this->_instances, $r); //verify triple in value query $propertiesWithTitles = $this->_instances->getShownProperties(); $this->assertCount(2, $propertiesWithTitles); } protected static function _onlyValues($arr) { $r = array(); foreach ($arr as $a) { if (isset($a['origvalue'])) { $r[] = $a['origvalue']; } else { if (isset($a['uri'])) { $r[] = $a['uri']; } else { $r[] = $a['value']; } } } return $r; } } ================================================ FILE: application/tests/integration/OntoWiki/Model/TitleHelperIntegrationTest.php ================================================ */ class OntoWiki_Model_TitleHelperIntegrationTest extends Erfurt_TestCase { /** @var Erfurt_Store_Adapter_test */ private $_storeAdapter = null; /** @var Erfurt_Store */ private $_store = null; private $_erfurtApp = null; public function setUp() { $this->markTestNeedsTestConfig(); $this->markTestNeedsDatabase(); $this->_erfurtApp = Erfurt_App::getInstance(); $this->_store = $this->_erfurtApp->getStore(); $this->authenticateDbUser(); $this->_modelUri = 'http://example.org/graph123/'; $this->_addTestData(); parent::setUp(); } private function _addTestData() { $model = $this->_store->getNewModel( $this->_modelUri, '', Erfurt_Store::MODEL_TYPE_OWL, false ); $this->authenticateDbUser(); $turtleString = ' ' . ' "testABC_en"@en .' . ' ' . ' "testABC_noLang" ;' . ' ' . ' "testABC_de"@de .' . ' ' . ' "testABC" ;' . ' ' . ' "testMenuLabel" .'; $this->_store->importRdf( $this->_modelUri, $turtleString, 'turtle', Erfurt_Syntax_RdfParser::LOCATOR_DATASTRING, false ); } public function testMultipleAddResourceGetTitleCallsGithubIssue65() { $graph = new Erfurt_Rdf_Model($this->_modelUri); $properties = array( 'testABC_en@en' => 'http://purl.org/dc/terms/title', 'testABC_de@de' => 'http://example.org/resourceXYZ', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' ); $config = array( 'titleHelper' => array( 'properties' => array( 'skosPlabel' => 'http://www.w3.org/2004/02/skos/core#prefLabel', 'dcTitle' => 'http://purl.org/dc/elements/1.1/title', 'dcTitle2' => 'http://purl.org/dc/terms/title', 'swrcTitle' => 'http://swrc.ontoware.org/ontology#title', 'foafName' => 'http://xmlns.com/foaf/0.1/name', 'doapName' => 'http://usefulinc.com/ns/doap#name', 'siocName' => 'http://rdfs.org/sioc/ns#name', 'tagName' => 'http://www.holygoat.co.uk/owl/redwood/0.1/tags/name', 'lgeodName' => 'http://linkedgeodata.org/vocabulary#name', 'geoName' => 'http://www.geonames.org/ontology#name', 'goName' => 'http://www.geneontology.org/dtds/go.dtd#name', 'rdfsLabel' => 'http://www.w3.org/2000/01/rdf-schema#label' ), 'searchMode' => 'language' ) ); $titleHelper = new OntoWiki_Model_TitleHelper($graph, $this->_store, $config); foreach ($properties as $expected => $property) { $resource = $property; $lang = null; $expectedTitle = $expected; if (strpos($expected, '@') !== false) { $parts = explode('@', $expected); $expectedTitle = $parts[0]; $lang = $parts[1]; } $titleHelper->addResource($resource); $title = $titleHelper->getTitle($property, $lang); $this->assertEquals($expectedTitle, $title); } } public function testPrependTitlePropertyDifferentInstances() { $config = array( 'titleHelper' => array( 'properties' => array( 'skosPlabel' => 'http://www.w3.org/2004/02/skos/core#prefLabel', 'dcTitle' => 'http://purl.org/dc/elements/1.1/title', 'dcTitle2' => 'http://purl.org/dc/terms/title', 'swrcTitle' => 'http://swrc.ontoware.org/ontology#title', 'foafName' => 'http://xmlns.com/foaf/0.1/name', 'doapName' => 'http://usefulinc.com/ns/doap#name', 'siocName' => 'http://rdfs.org/sioc/ns#name', 'tagName' => 'http://www.holygoat.co.uk/owl/redwood/0.1/tags/name', 'lgeodName' => 'http://linkedgeodata.org/vocabulary#name', 'geoName' => 'http://www.geonames.org/ontology#name', 'goName' => 'http://www.geneontology.org/dtds/go.dtd#name', 'rdfsLabel' => 'http://www.w3.org/2000/01/rdf-schema#label' ), 'searchMode' => 'language' ) ); $graph = new Erfurt_Rdf_Model($this->_modelUri); $resource = 'http://example.org/graph123/resourceABC'; $titleHelper = new OntoWiki_Model_TitleHelper($graph, $this->_store, $config); $titleHelper->addResource($resource); $title = $titleHelper->getTitle($resource); $this->assertEquals('testABC', $title); // now prepend a property $titleHelper = new OntoWiki_Model_TitleHelper($graph, $this->_store, $config); $titleHelper->prependTitleProperty('http://ns.ontowiki.net/SysOnt/Site/menuLabel'); $titleHelper->addResource($resource); $title = $titleHelper->getTitle($resource); $this->assertEquals('testMenuLabel', $title); } public function testPrependTitlePropertySameInstances() { $config = array( 'titleHelper' => array( 'properties' => array( 'skosPlabel' => 'http://www.w3.org/2004/02/skos/core#prefLabel', 'dcTitle' => 'http://purl.org/dc/elements/1.1/title', 'dcTitle2' => 'http://purl.org/dc/terms/title', 'swrcTitle' => 'http://swrc.ontoware.org/ontology#title', 'foafName' => 'http://xmlns.com/foaf/0.1/name', 'doapName' => 'http://usefulinc.com/ns/doap#name', 'siocName' => 'http://rdfs.org/sioc/ns#name', 'tagName' => 'http://www.holygoat.co.uk/owl/redwood/0.1/tags/name', 'lgeodName' => 'http://linkedgeodata.org/vocabulary#name', 'geoName' => 'http://www.geonames.org/ontology#name', 'goName' => 'http://www.geneontology.org/dtds/go.dtd#name', 'rdfsLabel' => 'http://www.w3.org/2000/01/rdf-schema#label' ), 'searchMode' => 'language' ) ); $graph = new Erfurt_Rdf_Model('http://example.org/graph123/'); $resource = 'http://example.org/graph123/resourceABC'; $titleHelper = new OntoWiki_Model_TitleHelper($graph, $this->_store, $config); $title = $titleHelper->getTitle($resource); $this->assertEquals('testABC', $title); // now prepend a property $titleHelper->prependTitleProperty('http://ns.ontowiki.net/SysOnt/Site/menuLabel'); $title = $titleHelper->getTitle($resource); $this->assertEquals('testMenuLabel', $title); } } ================================================ FILE: application/tests/integration/controller/ModelControllerTest.php ================================================ */ class ModelControllerTest extends OntoWiki_Test_ControllerTestCase { public function setUp() { $this->setUpIntegrationTest(); //this is necessary to allow the dispatch to create a model (ac) $this->frontEndLogin(); } /** * @dataProvider uriProvider */ public function testCreateActionFiltersOnlyIncorrectUris($uri, $correctUri) { $this->dispatch('/service/auth'); $this->request->setPost( array( 'title' => 'test', 'modeluri' => $uri, 'importOptions' => 'import-empty' ) ); $this->dispatch('/model/create'); $this->assertController('model'); $this->assertAction('create'); //when the URI is correct expect the model in the store $store = OntoWiki::getInstance()->erfurt->getStore(); if ($correctUri) { $this->assertTrue($store->isModelAvailable($uri, true)); } else { $this->assertFalse($store->isModelAvailable($uri, true)); } } public function uriProvider() { return [ ['ftp://ftp.is.co.za.example.org/ontowiki/ontowiki.txt', true], ['gopher://spinaltap.micro.umn.example.edu/00/Weather/California/Los%20Angeles', true], ['http://www.ontowiki.aksw.no.example.net/faq/ontowiki-faq/part1.html', true], ['mailto:aksw@ifi.unizh.example.gov', true], ['news:comp.aksw.www.servers.unix', true], ['telnet://melvyl.ucop.example.edu/', true], ['http://www.ietf.org/rfc/rfc2396.txt', true], ['ldap://[2001:db8::7]/c=GB?objectClass?one', true], ['mailto:AKSW.L@example.com', true], ['telnet://192.0.2.16:80/', true], ['urn:oasis:names:specification:docbook:dtd:xml:4.1.2', true], ['https://www.aksw.org/faq', true], ['ptth://www.aksw.org', true], ['\\äüö', false], ['plainText', false], ['noProtocol.de', false], ['http://www.äß', false], ['http://www.⺅⺔.com', false] ]; } } ================================================ FILE: application/tests/integration/controller/ServiceControllerTest.php ================================================ * @author Konrad Abicht */ class ServiceControllerTest extends OntoWiki_Test_ControllerTestCase { public function setUp() { $this->setUpIntegrationTest(); } // ------------------------------------------------------------------------ // Auth Action // ------------------------------------------------------------------------ public function testCallWithoutActionShouldPullFromIndexAction() { $this->dispatch('/service'); // We expect the error controller with error action here, since there is // no default index action for this controller. $this->assertController('error'); $this->assertAction('error'); } public function testAuthActionGetNotAllowed() { $config = OntoWiki::getInstance()->config; $config->service->auth->allowGet = false; $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); // TODO: Remove the @ again, when the ZF issue is resolved // Currently there is a interface mismatch between PHPUnit >= 3.6 and ZF 1.x @$this->assertResponseCode(405); $this->assertHeaderContains('allow', 'POST'); } /** * We enable GET authentication and test that we do not get a * 405 Method No Allowed response. */ public function testAuthActionGetAllowed() { $config = OntoWiki::getInstance()->config; $config->service->allowGetAuth = true; $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(400); } public function testAuthActionNoParams() { $this->request->setMethod('POST'); $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(400); } public function testAuthActionLogoutTrue() { $this->request->setMethod('POST')->setPost( array( 'logout' => 'true' ) ); $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(200); } public function testAuthActionLogoutInvalidValue() { $this->request->setMethod('POST')->setPost( array( 'logout' => 'xyz' ) ); $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(400); } public function testAuthActionAnonymousUserNoPasswordSuccess() { $this->request->setMethod('POST')->setPost( array( 'u' => 'Anonymous' ) ); $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(200); } public function testAuthActionAnonymousUserPasswordSetSuccess() { $this->request->setMethod('POST')->setPost( array( 'u' => 'Anonymous', 'p' => '' ) ); $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(200); } public function testAuthActionInvalidUser() { $this->request->setMethod('POST')->setPost( array( 'u' => 'xyz', 'p' => '123' ) ); $this->dispatch('/service/auth'); $this->assertController('service'); $this->assertAction('auth'); $this->assertResponseCode(401); } // ------------------------------------------------------------------------ // SPARQL Action // ------------------------------------------------------------------------ /** * No parameter, no action! * * @test */ public function sparqlNoParameter() { $this->request->setMethod('POST'); $this->dispatch('/service/sparql'); $this->assertController('service'); $this->assertAction('sparql'); $this->assertResponseCode(200); } /** * No authentification, but with a query. OW should use Anonymous. * * @test */ public function sparqlNoAuthWithInvalidQuery() { // Send invalid query $this->request->setMethod('POST')->setPost( array('query' => '123') ); $this->dispatch('/service/sparql'); $code = $this->_response->getHttpResponseCode(); $this->assertController('service'); $this->assertAction('sparql'); $this->assertResponseCode(400, "$code returned instead"); } // ------------------------------------------------------------------------ // Update Action // ------------------------------------------------------------------------ public function testUpdateDoesNothingWithEmptyParameters() { $this->request->setMethod('POST') ->setPost(array('insert' => '{}', 'delete' => '{}')); $this->dispatch('/service/update'); $this->assertController('service'); $this->assertAction('update'); $this->assertResponseCode(200); } } ================================================ FILE: application/tests/integration/phpunit.xml.dist ================================================ . ../../../application ../../../application/scripts ../../../application/tests ../../../application/shell.worker.client.php ../../../application/shell.worker.php ================================================ FILE: application/tests/unit/OntoWiki/Extension/ManagerTest.php ================================================ */ class ManagerTest extends PHPUnit_Framework_TestCase { public function testTriple2ConfigArray() { $triples = array( 'file:///home/jonas/programming/php-workspace/ow/extensions/account/' => array( 'http://xmlns.com/foaf/0.1/primaryTopic' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/account/raw/master/doap.n3#account', ), ), ), 'https://github.com/AKSW/account/raw/master/doap.n3#account' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://usefulinc.com/ns/doap#Project', ), ), 'http://usefulinc.com/ns/doap#name' => array( 0 => array( 'type' => 'literal', 'value' => 'account', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/privateNamespace' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/account/raw/master/doap.n3#', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/enabled' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Login Module', ), ), 'http://usefulinc.com/ns/doap#description' => array( 0 => array( 'type' => 'literal', 'value' => 'provides a login module and a recover action.', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/authorLabel' => array( 0 => array( 'type' => 'literal', 'value' => 'AKSW', ), ), 'http://usefulinc.com/ns/doap#maintainer' => array( 0 => array( 'type' => 'uri', 'value' => 'http://aksw.org', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/templates' => array( 0 => array( 'type' => 'literal', 'value' => 'templates', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/languages' => array( 0 => array( 'type' => 'literal', 'value' => 'languages', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/hasModule' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/account/raw/master/doap.n3#Default', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node1', ), ), 'http://usefulinc.com/ns/doap#release' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/account/raw/master/doap.n3#v1-0', ), ), ), 'https://github.com/AKSW/account/raw/master/doap.n3#Default' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Module', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Default', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/caching' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/priority' => array( 0 => array( 'type' => 'literal', 'value' => '40', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/context' => array( 0 => array( 'type' => 'literal', 'value' => 'main.sidewindows', ), ), ), '_:node1' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'allow', ), ), 'https://github.com/AKSW/account/raw/master/doap.n3#local' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/account/raw/master/doap.n3#webid' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/account/raw/master/doap.n3#openid' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), 'https://github.com/AKSW/account/raw/master/doap.n3#v1-0' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://usefulinc.com/ns/doap#Version', ), ), 'http://usefulinc.com/ns/doap#revision' => array( 0 => array( 'type' => 'literal', 'value' => '1.0', ), ), ), ); $base = 'file:///home/jonas/programming/php-workspace/ow/extensions/account/'; $conf = OntoWiki_Extension_Manager::triples2configArray($triples, "test", $base, "file:///tmp/test"); $this->assertEquals('account', $conf['name']); $this->assertEquals('Login Module', $conf['title']); $this->assertTrue($conf['private']['allow']['openid']); $this->assertFalse($conf['private']['allow']['webid']); } public function testTriple2ConfigArray2() { $triples = array( 'file:///home/jonas/programming/php-workspace/ow/extensions/navigation/' => array( 'http://xmlns.com/foaf/0.1/primaryTopic' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/navigation/raw/master/doap.n3#navigation', ), ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#navigation' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://usefulinc.com/ns/doap#Project', ), ), 'http://usefulinc.com/ns/doap#name' => array( 0 => array( 'type' => 'literal', 'value' => 'navigation', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/privateNamespace' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/navigation/raw/master/doap.n3#', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/enabled' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Navigation Module', ), ), 'http://usefulinc.com/ns/doap#description' => array( 0 => array( 'type' => 'literal', 'value' => 'an extensible and highly customizable module to navigate in knowledge bases ' . 'via tree-based information (e.g. classes)', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/authorLabel' => array( 0 => array( 'type' => 'literal', 'value' => 'AKSW', ), ), 'http://usefulinc.com/ns/doap#maintainer' => array( 0 => array( 'type' => 'uri', 'value' => 'http://aksw.org', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/templates' => array( 0 => array( 'type' => 'literal', 'value' => 'templates', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/languages' => array( 0 => array( 'type' => 'literal', 'value' => 'languages', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/hasModule' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/navigation/raw/master/doap.n3#Default', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node1', ), 1 => array( 'type' => 'bnode', 'value' => '_:node2', ), 2 => array( 'type' => 'bnode', 'value' => '_:node4', ), ), 'http://usefulinc.com/ns/doap#release' => array( 0 => array( 'type' => 'uri', 'value' => 'https://github.com/AKSW/navigation/raw/master/doap.n3#v1-0', ), ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#Default' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Module', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Default', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/context' => array( 0 => array( 'type' => 'literal', 'value' => 'main.sidewindows', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/priority' => array( 0 => array( 'type' => 'literal', 'value' => '30', ), ), ), '_:node1' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'defaults', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#config' => array( 0 => array( 'type' => 'literal', 'value' => 'classes', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#limit' => array( 0 => array( 'type' => 'literal', 'value' => '10', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkTypes' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showMenu' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node2' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'sorting', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node3', ), ), ), '_:node3' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'label', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'By Label', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2000/01/rdf-schema#label', ), ), ), '_:node4' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node5', ), 1 => array( 'type' => 'bnode', 'value' => '_:node9', ), 2 => array( 'type' => 'bnode', 'value' => '_:node13', ), 3 => array( 'type' => 'bnode', 'value' => '_:node16', ), 4 => array( 'type' => 'bnode', 'value' => '_:node19', ), 5 => array( 'type' => 'bnode', 'value' => '_:node22', ), 6 => array( 'type' => 'bnode', 'value' => '_:node25', ), 7 => array( 'type' => 'bnode', 'value' => '_:node28', ), ), ), '_:node5' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'classes', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Classes', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#cache' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkVisibility' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2002/07/owl#Class', ), 1 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2000/01/rdf-schema#Class', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node6', ), 1 => array( 'type' => 'bnode', 'value' => '_:node7', ), 2 => array( 'type' => 'bnode', 'value' => '_:node8', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hiddenNS' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#', ), 1 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2000/01/rdf-schema#', ), 2 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2002/07/owl#', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hiddenRelation' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/hidden', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showImplicitElements' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showEmptyElements' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showCounts' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkSub' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hideDefaultHierarchy' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node6' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2000/01/rdf-schema#subClassOf', ), ), ), '_:node7' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'instanceRelation', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', ), ), ), '_:node8' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'list', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#config' => array( 0 => array( 'type' => 'literal', 'value' => '{|filter|:[{|rdfsclass|:|%resource%|,|mode|:|rdfsclass|}]}', ), ), ), '_:node9' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'properties', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Properties', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/1999/02/22-rdf-syntax-ns#Property', ), 1 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2002/07/owl#DatatypeProperty', ), 2 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2002/07/owl#ObjectProperty', ), 3 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2002/07/owl#AnnotationProperty', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node10', ), 1 => array( 'type' => 'bnode', 'value' => '_:node11', ), 2 => array( 'type' => 'bnode', 'value' => '_:node12', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showImplicitElements' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showEmptyElements' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showCounts' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hideDefaultHierarchy' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkSub' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node10' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2000/01/rdf-schema#subPropertyOf', ), ), ), '_:node11' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'instanceRelation', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2000/01/rdf-schema#subPropertyOf', ), ), ), '_:node12' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'list', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#config' => array( 0 => array( 'type' => 'literal', 'value' => '{|shownProperties|:[{|uri|:|%resource%|,|label|:|Label 1|,|action|:|add|,' . '|inverse|:false}],|filter|:[{|property|:|%resource%|,|filter|:|bound|}]}', ), ), ), '_:node13' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'spatial', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Spatial', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/SpatialArea', ), 1 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/Planet', ), 2 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/Continent', ), 3 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/Country', ), 4 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/Province', ), 5 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/District', ), 6 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/City', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node14', ), 1 => array( 'type' => 'bnode', 'value' => '_:node15', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), ), '_:node14' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/spatialHierarchy/isLocatedIn', ), ), ), '_:node15' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'instanceRelation', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/addressFeatures/physical/country', ), 1 => array( 'type' => 'uri', 'value' => 'http://ns.aksw.org/addressFeatures/physical/city', ), ), ), '_:node16' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'faun', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Faunistics', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#Family', ), 1 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#Genus', ), 2 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#Species', ), 3 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#Order', ), 4 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#SubOrder', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node17', ), 1 => array( 'type' => 'bnode', 'value' => '_:node18', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkSub' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node17' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#subTaxonOf', ), ), ), '_:node18' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'instanceRelation', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://purl.org/net/faunistics#identifiesAs', ), ), ), '_:node19' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'skos', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'SKOS', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2004/02/skos/core#Concept', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node20', ), 1 => array( 'type' => 'bnode', 'value' => '_:node21', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showCounts' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node20' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2004/02/skos/core#broader', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2004/02/skos/core#narrower', ), ), ), '_:node21' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'instanceRelation', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2004/02/skos/core#narrower', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.w3.org/2004/02/skos/core#broader', ), ), ), '_:node22' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'org', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Groups', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://xmlns.com/foaf/0.1/Group', ), 1 => array( 'type' => 'uri', 'value' => 'http://xmlns.com/foaf/0.1/Organization', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node23', ), 1 => array( 'type' => 'bnode', 'value' => '_:node24', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showCounts' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node23' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/subGroup', ), ), ), '_:node24' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'instanceRelation', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://xmlns.com/foaf/0.1/member', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#out' => array( 0 => array( 'type' => 'uri', 'value' => 'http://xmlns.com/foaf/0.1/member_of', ), ), ), '_:node25' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'go', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Gene Ontology', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.geneontology.org/dtds/go.dtd#term', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node26', ), 1 => array( 'type' => 'bnode', 'value' => '_:node27', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#showCounts' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkSub' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hideDefaultHierarchy' => array( 0 => array( 'type' => 'literal', 'value' => 'false', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), ), '_:node26' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.geneontology.org/dtds/go.dtd#is_a', ), ), ), '_:node27' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'list', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#query' => array( 0 => array( 'type' => 'literal', 'value' => 'SELECT DISTINCT ?resourceUri WHERE { ?resourceUri <%resource%> }', ), ), ), '_:node28' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'checklist', ), ), 'http://www.w3.org/2000/01/rdf-schema#label' => array( 0 => array( 'type' => 'literal', 'value' => 'Checklist', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#titleMode' => array( 0 => array( 'type' => 'literal', 'value' => 'titleHelper', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#hierarchyTypes' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.mindswap.org/2003/owl/geo/geoFeatures.owl#Country', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/config' => array( 0 => array( 'type' => 'bnode', 'value' => '_:node29', ), 1 => array( 'type' => 'bnode', 'value' => '_:node30', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#checkSub' => array( 0 => array( 'type' => 'literal', 'value' => 'true', 'datatype' => 'http://www.w3.org/2001/XMLSchema#boolean', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#rootName' => array( 0 => array( 'type' => 'literal', 'value' => 'Caucasus Spiders', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#rootURI' => array( 0 => array( 'type' => 'uri', 'value' => 'http://db.caucasus-spiders.info/Area/152', ), ), ), '_:node29' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'hierarchyRelations', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#in' => array( 0 => array( 'type' => 'uri', 'value' => 'http://www.mindswap.org/2003/owl/geo/geoFeatures.owl#within', ), ), ), '_:node30' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/Config', ), ), 'http://ns.ontowiki.net/SysOnt/ExtensionConfig/id' => array( 0 => array( 'type' => 'literal', 'value' => 'list', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#shownProperties' => array( 0 => array( 'type' => 'literal', 'value' => '{|uri|:|http://purl.org/net/faunistics#citationSuffix|,|label|:|citation suffix|' . ',|action|:|add|,|inverse|:false}', ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#query' => array( 0 => array( 'type' => 'literal', 'value' => '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%>)) }', ), ), ), 'https://github.com/AKSW/navigation/raw/master/doap.n3#v1-0' => array( 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type' => array( 0 => array( 'type' => 'uri', 'value' => 'http://usefulinc.com/ns/doap#Version', ), ), 'http://usefulinc.com/ns/doap#revision' => array( 0 => array( 'type' => 'literal', 'value' => '1.0', ), ), ), ); $base = 'file:///home/jonas/programming/php-workspace/ow/extensions/navigation/'; $conf = OntoWiki_Extension_Manager::triples2configArray($triples, "navigation", $base, "file:///tmp/test"); $this->assertArrayHasKey('private', $conf); } } ================================================ FILE: application/tests/unit/OntoWiki/Extension/_files/test-doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :test . :test a doap:Project ; doap:name "test" ; owconfig:privateNamespace ; owconfig:enabled "true"^^xsd:boolean ; rdfs:label "Some Extension" ; 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" . :prop "val" :test owconfig:config [ a owconfig:Config; owconfig:id "sub"; :bool "true"^^xsd:boolean ; :int "5"^^xsd:int ; :float "0.5"^^xsd:float ] ; doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: application/tests/unit/OntoWiki/MenuTest.php ================================================ _menu = new OntoWiki_Menu(); } public function testSetEntryString() { $this->_menu->setEntry('Entry 1', 'Value 1'); $this->assertEquals($this->_menu->toArray(), array('Entry 1' => 'Value 1')); } public function testSetEntryObject() { $subMenuA = new OntoWiki_Menu(); $subMenuA->setEntry('Sub Entry 1', 'Sub Value 1'); $this->_menu->setEntry('Sub Menu 1', $subMenuA); $this->assertEquals($this->_menu->toArray(), array('Sub Menu 1' => array('Sub Entry 1' => 'Sub Value 1'))); } public function testReplaceEntry() { $this->_menu->setEntry('Entry 1', 'Old Value') ->setEntry('Entry 1', 'New Value'); $this->assertEquals($this->_menu->toArray(), array('Entry 1' => 'New Value')); } public function testToArray() { $subMenuA = new OntoWiki_Menu(); $subMenuA->setEntry('Sub Entry 1', 'Sub Value 1'); $subMenuB = new OntoWiki_Menu(); $subMenuB->setEntry('Sub Entry 2', 'Old Sub Value 2') ->setEntry('Sub Entry 2', 'New Sub Value 2'); $this->_menu->setEntry('Entry 1', 'Value 1') ->setEntry('Sub Menu 1', $subMenuA) ->setEntry('Sub Menu 2', $subMenuB); $expected = array( 'Entry 1' => 'Value 1', 'Sub Menu 1' => array('Sub Entry 1' => 'Sub Value 1'), 'Sub Menu 2' => array('Sub Entry 2' => 'New Sub Value 2') ); $this->assertEquals($this->_menu->toArray(), $expected); $this->_menu->setEntry('Sub Menu 1', 'Replaced Sub Menu Entry'); $expected = array( 'Entry 1' => 'Value 1', 'Sub Menu 1' => 'Replaced Sub Menu Entry', 'Sub Menu 2' => array('Sub Entry 2' => 'New Sub Value 2') ); $this->assertEquals($this->_menu->toArray(), $expected); } public function testToJson() { $subMenuA = new OntoWiki_Menu(); $subMenuA->setEntry('Sub Entry 1', 'Sub Value 1'); $subMenuB = new OntoWiki_Menu(); $subMenuB->setEntry('Sub Entry 2', 'Old Sub Value 2') ->setEntry('Sub Entry 2', 'New Sub Value 2'); $this->_menu->setEntry('Entry 1', 'Value 1') ->setEntry('Sub Menu 1', $subMenuA) ->setEntry('Sub Menu 2', $subMenuB); $expected = '{"Entry 1":"Value 1","Sub Menu 1":{"Sub Entry 1":"Sub Value 1"},' . '"Sub Menu 2":{"Sub Entry 2":"New Sub Value 2"}}'; $this->assertEquals($expected, $this->_menu->toJson(false)); $this->_menu->setEntry('Sub Menu 1', 'Replaced Sub Menu Entry'); $expected = '{"Entry 1":"Value 1","Sub Menu 1":"Replaced Sub Menu Entry","Sub Menu 2":' . '{"Sub Entry 2":"New Sub Value 2"}}'; $this->assertEquals($expected, $this->_menu->toJson(false)); } /** * @expectedException OntoWiki_Exception */ public function testWrongKey() { $this->_menu->setEntry(null, 'Bar'); } /** * @expectedException OntoWiki_Exception */ public function testContentError() { $this->_menu->setEntry('Foo', 12345); } /** * @expectedException OntoWiki_Exception */ public function testReplaceError() { $this->_menu->setEntry('Existing Key', 'Bar'); $this->_menu->setEntry('Existing Key', 'Baz', false); } } ================================================ FILE: application/tests/unit/OntoWiki/MessageTest.php ================================================ * @author Philipp Frischmuth */ class OntoWiki_MessageTest extends PHPUnit_Framework_TestCase { public function testMessageGetTypeDefaultInfo() { $msg = new OntoWiki_Message('ttt'); $this->assertEquals($msg->getType(), OntoWiki_Message::INFO); } public function testMessageGetTypeSuccess() { $msg = new OntoWiki_Message('ttt', OntoWiki_Message::SUCCESS); $this->assertEquals($msg->getType(), OntoWiki_Message::SUCCESS); } public function testMessageGetTypeInfo() { $msg = new OntoWiki_Message('ttt', OntoWiki_Message::INFO); $this->assertEquals($msg->getType(), OntoWiki_Message::INFO); } public function testMessageGetTypeWarning() { $msg = new OntoWiki_Message('ttt', OntoWiki_Message::WARNING); $this->assertEquals($msg->getType(), OntoWiki_Message::WARNING); } public function testMessageGetTypeError() { $msg = new OntoWiki_Message('ttt', OntoWiki_Message::ERROR); $this->assertEquals($msg->getType(), OntoWiki_Message::ERROR); } public function testMessageGetText() { $msg = new OntoWiki_Message('The test string for the message object.', OntoWiki_Message::SUCCESS); $this->assertEquals($msg->getText(), 'The test string for the message object.'); } } ================================================ FILE: application/tests/unit/OntoWiki/Model/InstancesTest.php ================================================ */ class OntoWiki_Model_InstancesTest extends Erfurt_TestCase { /** * * @var OntoWiki_Model_Instances */ protected $_instances = null; /** * * @var Erfurt_Store_Adapter */ protected $_storeAdapter = null; /** * * @var Erfurt_Store */ protected $_store = null; public function setUp() { $this->markTestNeedsTestConfig(); $this->_storeAdapter = new Erfurt_Store_Adapter_Test(); $this->_store = new Erfurt_Store( array( 'adapterInstance' => $this->_storeAdapter ), 'Test' ); $this->_store->setAc(new Erfurt_Ac_Test()); $this->_instances = new OntoWiki_Model_Instances( $this->_store, new Erfurt_Rdf_Model('http://graph.com/123/', null, $this->_store) ); } public function testGetResourceQuery() { $this->assertInstanceOf('Erfurt_Sparql_Query2', $this->_instances->getResourceQuery()); } public function testSerialization() { ob_start(); $this->_instances = unserialize(serialize($this->_instances)); $output = ob_get_contents(); ob_end_clean(); $this->assertTrue(empty($o)); //no warnings } public function testSetStore() { $adapter = new Erfurt_Store_Adapter_Test(); $store = new Erfurt_Store(array('adapterInstance' => $adapter), 'Test'); $this->assertNotSame($this->_instances->getStore(), $store); $this->_instances->setStore($store); $this->assertSame($this->_instances->getStore(), $store); try { $this->_instances->setStore(null); $this->fail("No Exception was thrown in setStore(null)"); } catch (Exception $e) { $this->assertTrue(true); //increase assertion count :) } } public function testAllTriple() { $this->assertTrue( in_array( $this->_instances->getAllTriple(), $this->_instances->getResourceQuery()->getWhere()->getElements() ) ); $this->_instances->removeAllTriple(); $this->assertTrue( !in_array( $this->_instances->getAllTriple(), $this->_instances->getResourceQuery()->getWhere()->getElements() ) ); $this->_instances->addAllTriple(); $this->assertTrue( in_array( $this->_instances->getAllTriple(), $this->_instances->getResourceQuery()->getWhere()->getElements() ) ); } public function testGetQuery() { $this->assertInstanceOf('Erfurt_Sparql_Query2', $this->_instances->getQuery()); } public function testGetResourceVar() { $this->assertInstanceOf('Erfurt_Sparql_Query2_Var', $this->_instances->getResourceVar()); } public function testOffsetLimit() { //default values $this->assertEquals(10, $this->_instances->getLimit()); $this->assertEquals(0, $this->_instances->getOffset()); //test setting $this->_instances->setOffset(1); $this->_instances->setLimit(1); $this->assertEquals(1, $this->_instances->getLimit()); $this->assertEquals(1, $this->_instances->getOffset()); //test repeated set $this->_instances->setOffset(1); $this->_instances->setLimit(1); //test negative set (minus interpreted as plus) $this->_instances->setOffset(-1); $this->_instances->setLimit(-1); $this->assertEquals(1, $this->_instances->getLimit()); $this->assertEquals(1, $this->_instances->getOffset()); } public function testNoCache() { $instances = new OntoWiki_Model_Instances( $this->_store, new Erfurt_Rdf_Model('http://graph.com/123/', null, $this->_store), array(Erfurt_Store::USE_CACHE => false) ); $this->assertInstanceOf('OntoWiki_Model_Instances', $instances); } public function testSerialize() { $vqA = $this->_instances->getQuery()->getSparql(); $rqA = $this->_instances->getResourceQuery()->getSparql(); $q = unserialize(serialize($this->_instances)); $vqB = $this->_instances->getQuery()->getSparql(); $rqB = $this->_instances->getResourceQuery()->getSparql(); $this->assertEquals($vqA, $vqB); $this->assertEquals($rqA, $rqB); $c = clone $this->_instances; $vqB = $c->getQuery()->getSparql(); $rqB = $c->getResourceQuery()->getSparql(); $this->assertEquals($vqA, $vqB); $this->assertEquals($rqA, $rqB); $this->assertNotSame($this->_instances, $c); } public function testCallMagic() { //redirect from methods to both query objects $from = new Erfurt_Sparql_Query2_GraphClause( new Erfurt_Sparql_Query2_IriRef("http://abc") ); $this->_instances->addFrom($from); $this->assertContains($from, $this->_instances->getFroms()); //redirected to resource query $this->assertContains($from, $this->_instances->getQuery()->getFroms()); //check undefined exception try { $r = $this->_instances->undef(); $this->fail("no exception when calling undefined method on instances object. see __call"); } catch (Exception $exc) { $this->assertTrue(true); //increase assertion count :) } } /** * number of triples that are in an "empty" value query * * @var int */ private $_valueQueryDefaultTriples = 3; public function testShownPropertiesEmpty() { //test default state $this->assertNoShownProperties($this->_instances); } public function testShownPropertiesAdd() { //add $r = $this->_instances->addShownProperty("http://abc"); //test chaining $this->assertSame($this->_instances, $r); return $this->_instances; } /** * * @depends testShownPropertiesAdd */ public function testShownPropertiesAddPlain(OntoWiki_Model_Instances $i) { $psDef = $i->getShownPropertiesPlain(); $this->assertCount(2, $psDef); } /** * * @depends testShownPropertiesAdd */ public function testShownPropertiesAddTriple(OntoWiki_Model_Instances $i) { //verify two triple in value query, alltriple (?resourceuri ?p ?o), filter(isuri) and the optional triple $triples = $i->getValueQuery()->getElements(); $this->assertCount(1 + $this->_valueQueryDefaultTriples, $triples); } /** * */ public function testShownPropertiesCustomAddTriple() { $var = new Erfurt_Sparql_Query2_Var("sp"); $triples = array( new Erfurt_Sparql_Query2_Triple( $this->_instances->getResourceVar(), new Erfurt_Sparql_Query2_IriRef('http://ex.com/'), $var ) ); $r = $this->_instances->addShownPropertyCustom($triples, $var); //verify two triple in value query, alltriple (?resourceuri ?p ?o), filter(isuri) and the optional triple $triplesQuery = $this->_instances->getValueQuery()->getElements(); $this->assertCount(1 + $this->_valueQueryDefaultTriples, $triplesQuery); } public function testtShownPropertiesRemove() { //add $p = "http://abc"; $this->_instances->addShownProperty($p); //result of add is checked in testShownPropertiesAdd1 $rA = $this->_instances->removeShownProperty($p, false); $this->assertNoShownProperties($this->_instances); $this->assertTrue($rA); //remove non existing $rB = $this->_instances->removeShownProperty($p, false); $this->assertFalse($rB); } private function assertNoShownProperties(OntoWiki_Model_Instances $i) { //only __TYPE $psDef = $i->getShownPropertiesPlain(); $this->assertCount(1, $psDef); $triples = $i->getValueQuery()->getElements(); $this->assertCount($this->_valueQueryDefaultTriples, $triples); } public function testFilterEmpty() { $fDef = $this->_instances->getFilter(); $this->assertEmpty($fDef); } public function testFilterAddBound() { //test add $this->_instances->addFilter("http://abc", false, "abc", "bound"); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddContains() { $this->_instances->addFilter("http://abc", false, "abc", "contains", "xyz"); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddEquals() { $this->_instances->addFilter("http://abc", false, "abc", "equals", "xyz"); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddLarger() { $this->_instances->addFilter("http://abc", false, "abc", "larger", 4); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddSmaller() { $this->_instances->addFilter("http://abc", false, "abc", "smaller", 4); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddBetween() { $this->_instances->addFilter("http://abc", false, "abc", "between", 5, 6); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddType() { $this->_instances->addTypeFilter("http://class.com"); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddSearch() { $this->_instances->addSearchFilter("term"); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddTriples() { $triples = array( new Erfurt_Sparql_Query2_Triple( $this->_instances->getResourceVar(), new Erfurt_Sparql_Query2_IriRef('http://ex.com/'), new Erfurt_Sparql_Query2_Var("sp") ) ); $this->_instances->addTripleFilter($triples); //verify two triple in value query, alltriple (?resourceuri ?p ?o), filter(isuri) and the optional triple $triplesQuery = $this->_instances->getResourceQuery()->getElements(); $this->assertContains($triples[0], $triplesQuery); $this->assertCount(1, $this->_instances->getFilter()); } public function testFilterAddUndef() { //text unknown filter type try { $this->_instances->addFilter("http://abc", false, "abc", "undef"); $this->fail("no exception when calling filter method with unsupported filter type."); } catch (Exception $exc) { $this->assertTrue(true); //increase assertion count :) } //verify triple in value query } public function testFilterRemove() { //add $id = $this->_instances->addFilter("http://abc", false, "abc", "bound"); $fDef = $this->_instances->getFilter(); $this->assertCount(1, $fDef); $this->_instances->removeFilter($id); $fDefAfter = $this->_instances->getFilter(); $this->assertEmpty($fDefAfter); } public function testSetTitleHelper() { $newTH = new OntoWiki_Model_TitleHelper(null, $this->_store); $this->_instances->setTitleHelper($newTH); $this->assertSame($newTH, $this->_instances->getTitleHelper()); } public function testGetProperties() { $p = $this->_instances->getAllProperties(); $this->assertEmpty($p); //on a stub store, there should be no results } public function testGetPropertiesQuery() { $q = $this->_instances->getAllPropertiesQuery(); $this->assertInstanceOf('Erfurt_Sparql_Query2', $q); } public function testGetValues() { $v = $this->_instances->getValues(); $this->assertEmpty($v); //on a stub store, there should be no results } public function testResults() { $r = $this->_instances->getResults(); $this->assertArrayHasKey('results', $r); $this->assertArrayHasKey('bindings', $r['results']); $this->assertEmpty($r['results']['bindings']); //on a stub store, there should be no results } public function testPossibleValues() { $v = $this->_instances->getPossibleValues("http://abc"); $this->assertEmpty($v); //on a stub store, there should be no results } } ================================================ FILE: application/tests/unit/OntoWiki/Module/RegistryTest.php ================================================ _registry = OntoWiki_Module_Registry::getInstance(); } public function tearDown() { $this->_registry->resetInstance(); } public function testRegisterModuleEnabled() { $moduleName = 'test'; $this->_registry->register($moduleName, 'TestModule.php'); $this->assertEquals(true, $this->_registry->isModuleEnabled($moduleName)); } public function testRegisterModuleDisabled() { $moduleName = 'test'; $this->_registry->register( $moduleName, 'TestModule.php', OntoWiki_Module_Registry::DEFAULT_CONTEXT, array('enabled' => false) ); $this->assertEquals(false, $this->_registry->isModuleEnabled($moduleName)); } public function testDisableModule() { $moduleName = 'test'; $this->_registry->register($moduleName, 'TestModule.php'); $this->assertEquals(true, $this->_registry->isModuleEnabled($moduleName)); $this->_registry->disableModule($moduleName); $this->assertEquals(false, $this->_registry->isModuleEnabled($moduleName)); } public function testGetModulesReturnesAllModules() { $this->_registry->register('enabledmodule1', 'Enabledmodule1Module.php'); $this->assertEquals(true, $this->_registry->isModuleEnabled('enabledmodule1')); $this->_registry->register( 'disabledmodule', 'DisabledmoduleModule.php', OntoWiki_Module_Registry::DEFAULT_CONTEXT, array('enabled' => false) ); $this->assertEquals(false, $this->_registry->isModuleEnabled('disabledmodule')); $this->_registry->register('enabledmodule2', 'Enabledmodule2Module.php'); $this->assertEquals(true, $this->_registry->isModuleEnabled('enabledmodule2')); $expected = array( 'enabledmodule1' => array( 'enabled' => true, 'id' => 'enabledmodule1', 'classes' => '', 'name' => 'Enabledmodule1', 'extensionName' => 'enabledmodule1', 'private' => array() ), 'enabledmodule2' => array( 'enabled' => true, 'name' => 'Enabledmodule2', 'id' => 'enabledmodule2', 'classes' => '', 'extensionName' => 'enabledmodule2', 'private' => array() ), 'disabledmodule' => array( 'enabled' => false, 'name' => 'Disabledmodule', 'id' => 'disabledmodule', 'classes' => '', 'extensionName' => 'disabledmodule', 'private' => array() ) ); $actualModules = $this->_registry->getModules(); $this->assertTrue(isset($actualModules['enabledmodule1'])); $this->assertTrue(isset($actualModules['enabledmodule2'])); $this->assertTrue(isset($actualModules['disabledmodule'])); $this->assertEquals($expected['enabledmodule1'], $actualModules['enabledmodule1']->toArray()); $this->assertEquals($expected['enabledmodule2'], $actualModules['enabledmodule2']->toArray()); $this->assertEquals($expected['disabledmodule'], $actualModules['disabledmodule']->toArray()); } public function testGetModulesReturnesAllOptions() { $optionsA = array( 'enabled' => true, 'class' => 'foo-class', 'id' => 'bar-id', 'name' => 'foo', 'classes' => '', 'extensionName' => 'disabledmodule', 'private' => array() ); $this->_registry->register('foo', 'FooModule.php', OntoWiki_Module_Registry::DEFAULT_CONTEXT, $optionsA); $optionsB = array( 'enabled' => false, 'class' => 'fuu-class', 'id' => 'baz-id', 'name' => 'foo', 'classes' => '', 'extensionName' => 'disabledmodule', 'private' => array() ); $this->_registry->register('bar', 'BarModule.php', OntoWiki_Module_Registry::DEFAULT_CONTEXT, $optionsB); $actualModules = $this->_registry->getModules(); $this->assertTrue(isset($actualModules['foo'])); $this->assertTrue(isset($actualModules['bar'])); $this->assertEquals($optionsA, $actualModules['foo']->toArray()); $this->assertEquals($optionsB, $actualModules['bar']->toArray()); } } ================================================ FILE: application/tests/unit/OntoWiki/NavigationTest.php ================================================ _ontoWikiNavigation = new OntoWiki_Navigation(); } public function testRegisterKeyEmptyOptions() { $this->_ontoWikiNavigation->register('foo', array(), false); $check = array('foo' => array( 'route' => null, 'controller' => null, 'action' => null, 'name' => 'foo', 'active' => 'active' )); $this->assertEquals($check, $this->_ontoWikiNavigation->getNavigation()); } public function testRegisterKeyDefaultOptions() { $this->_ontoWikiNavigation->register( 'foo', array( 'route' => null, 'controller' => null, 'action' => null, 'name' => 'foo' ), false ); $check = array('foo' => array( 'route' => null, 'controller' => null, 'action' => null, 'name' => 'foo', 'active' => 'active' )); $this->assertEquals($check, $this->_ontoWikiNavigation->getNavigation()); } /** * @expectedException OntoWiki_Exception */ public function testRegisterAlreadyUsedKeyDefaultOptions() { $this->_ontoWikiNavigation->register( 'foo', array( 'route' => null, 'controller' => null, 'action' => null, 'name' => 'foo' ), false ); $this->_ontoWikiNavigation->register( 'foo', array( 'route' => null, 'controller' => null, 'action' => null, 'name' => 'foo' ), false ); } /** * @expectedException OntoWiki_Exception */ public function testRegisterAlreadyUsedKeyFilledOptions() { $this->_ontoWikiNavigation->register( 'foo', array( 'route' => 'foo', 'controller' => 'bar', 'action' => 'bar', 'name' => 'foo' ), false ); $this->_ontoWikiNavigation->register( 'foo', array( 'route' => 'foo', 'controller' => 'bar', 'action' => 'bar', 'name' => 'foo' ), false ); } /** * @expectedException OntoWiki_Exception */ public function testRegisterNoKey() { $this->_ontoWikiNavigation->register('', array(), false); } /** * @expectedException OntoWiki_Exception */ public function testRegisterNullKey() { $this->_ontoWikiNavigation->register(null, array(), false); } /** * @expectedException OntoWiki_Exception */ public function testRegisterNumberKey() { $this->_ontoWikiNavigation->register(0, array(), false); } /** * @expectedException OntoWiki_Exception */ public function testSetActiveNoKey() { $this->_ontoWikiNavigation->setActive(''); } /** * @expectedException OntoWiki_Exception */ public function testSetActiveNullKey() { $this->_ontoWikiNavigation->setActive(null); } public function testSetActiveKey() { $this->_ontoWikiNavigation->register('foo', array(), false); $this->_ontoWikiNavigation->setActive('foo'); $activeItem = $this->_ontoWikiNavigation->getActive(); $this->assertEquals('foo', $activeItem['name']); } public function testNoSetActiveKeyCheckActive() { $this->_ontoWikiNavigation->register('foo', array(), false); $activeItem = $this->_ontoWikiNavigation->getActive(); $this->assertEquals('foo', $activeItem['name']); } public function testNoSetActiveKeyCheckNotActiveMultipleItems() { $this->_ontoWikiNavigation->register('foo', array(), false); $this->_ontoWikiNavigation->register('bar', array(), false); $activeItem = $this->_ontoWikiNavigation->getActive(); $this->assertNotEquals('bar', $activeItem['name']); } public function testSetActiveKeyChangeActive() { $this->_ontoWikiNavigation->register('foo', array(), false); $this->_ontoWikiNavigation->register('oldActive', array(), false); $this->_ontoWikiNavigation->setActive('oldActive'); $this->_ontoWikiNavigation->setActive('foo'); $activeItem = $this->_ontoWikiNavigation->getActive(); $this->assertEquals('foo', $activeItem['name']); } } ================================================ FILE: application/tests/unit/OntoWiki/UtilsTest.php ================================================ */ class OntoWiki_UtilsTest extends PHPUnit_Framework_TestCase { public function testMatchMimetypeFromRequest() { $request = new Zend_Controller_Request_HttpTestCase(); $request->setHeader("Accept", "text/*"); $support = array( "text/ttl", "application/rdf+xml" ); $mime = OntoWiki_Utils::matchMimetypeFromRequest($request, $support); $this->assertEquals($mime, "text/ttl"); } } ================================================ FILE: application/tests/unit/OntoWikiTest.php ================================================ * @author Philipp Frischmuth */ class OntoWikiTest extends PHPUnit_Framework_TestCase { protected $_application; public function setUp() { $this->_application = OntoWiki::getInstance(); } public function testGetInstance() { $newInstance = OntoWiki::getInstance(); $this->assertSame($this->_application, $newInstance); } public function testSetValue() { $this->_application->foo = 'bar'; $this->assertEquals($this->_application->foo, 'bar'); } public function testIssetValue() { $this->assertEquals(isset($this->_application->anotherFoo), false); } public function testGetValue() { $this->assertEquals($this->_application->YetAnotherFoo, null); $this->_application->YetAnotherFoo = 'bar'; $this->assertEquals($this->_application->YetAnotherFoo, 'bar'); } } ================================================ FILE: application/tests/unit/controller/IndexControllerTest.php ================================================ * @author Philipp Frischmuth */ class IndexControllerTest extends OntoWiki_Test_ControllerTestCase { public function setUp() { $this->setUpUnitTest(); } public function testNoControllerAndActionDefaultToNewsAction() { $this->dispatch('/'); $this->assertController('index'); $this->assertAction('news'); } public function testInvalidActionNoDefaultActionDefaultsToNewsAction() { $config = OntoWiki::getInstance()->config; unset($config->index->default->controller); unset($config->index->default->action); $this->dispatch('/index/actionXYZNotExisting'); $this->assertController('index'); $this->assertAction('news'); } public function testInvalidActionDefaultsToConfiguredDefaultAction() { $config = OntoWiki::getInstance()->config; $config->index->default->controller = 'index'; $config->index->default->action = 'empty'; $this->dispatch('/index/actionXYZNotExisting'); $this->assertController('index'); $this->assertAction('empty'); } public function testInvalidActionWithMessagesDefaultsToMessagesAction() { $owApp = OntoWiki::getInstance(); $owApp->appendMessage(new OntoWiki_Message('Test Message')); $this->dispatch('/index/actionXYZNotExisting'); $this->assertController('index'); $this->assertAction('messages'); $this->assertQueryContentContains('p.messagebox', 'Test Message'); } public function testEmptyAction() { $this->dispatch('/index/'); $this->assertController('index'); $this->assertAction('news'); $this->assertQuery('div.section-mainwindows'); $this->assertQuery('div.section-sidewindows'); } public function testMessagesActionNoMessages() { $this->dispatch('/index/messages'); $this->assertController('index'); $this->assertAction('messages'); } public function testMessagesActionSingleMessage() { $owApp = OntoWiki::getInstance(); $owApp->appendMessage(new OntoWiki_Message('Test Message 123', OntoWiki_Message::INFO)); $this->dispatch('/index/messages'); $this->assertController('index'); $this->assertAction('messages'); $this->assertQueryContentContains('p.messagebox.info', 'Test Message 123'); } public function testMessagesActionMultipleMessages() { $owApp = OntoWiki::getInstance(); $owApp->appendMessage(new OntoWiki_Message('Test Message 123', OntoWiki_Message::INFO)); $owApp->appendMessage(new OntoWiki_Message('Error Message 456', OntoWiki_Message::ERROR)); $this->dispatch('/index/messages'); $this->assertController('index'); $this->assertAction('messages'); $this->assertQueryContentContains('p.messagebox.info', 'Test Message 123'); $this->assertQueryContentContains('p.messagebox.error', 'Error Message 456'); } public function testNewsActionSuccess() { $adapter = new Zend_Http_Client_Adapter_Test(); Zend_Feed::setHttpClient(new Zend_Http_Client(null, array('adapter' => $adapter))); $adapter->setResponse( new Zend_Http_Response( 200, array(), file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'aksw.rss') ) ); $this->dispatch('/index/news'); $this->assertController('index'); $this->assertAction('news'); $this->assertQueryContentContains('h1.title', 'News'); $this->assertQueryCount('div.messagebox.feed', 5); } public function testNewsActionFail() { $adapter = new Zend_Http_Client_Adapter_Test(); $adapter->setNextRequestWillFail(true); Zend_Feed::setHttpClient(new Zend_Http_Client(null, array('adapter' => $adapter))); $this->dispatch('/'); $this->assertController('index'); $this->assertAction('news'); $this->assertQueryContentContains('h1.title', 'News'); $this->assertQuery('p.messagebox.warning'); } public function testNewsshortActionSuccess() { $adapter = new Zend_Http_Client_Adapter_Test(); Zend_Feed::setHttpClient(new Zend_Http_Client(null, array('adapter' => $adapter))); $adapter->setResponse( new Zend_Http_Response( 200, array(), file_get_contents(dirname(__FILE__) . DIRECTORY_SEPARATOR . '_files' . DIRECTORY_SEPARATOR . 'aksw.rss') ) ); $this->dispatch('/index/newsshort'); $this->assertController('index'); $this->assertAction('newsshort'); $this->assertQueryCount('div.messagebox.feed', 3); } public function testNewsshortActionFail() { $adapter = new Zend_Http_Client_Adapter_Test(); $adapter->setNextRequestWillFail(true); Zend_Feed::setHttpClient(new Zend_Http_Client(null, array('adapter' => $adapter))); $this->dispatch('/index/newsshort'); $this->assertController('index'); $this->assertAction('newsshort'); $this->assertQuery('p.messagebox.warning'); } } ================================================ FILE: application/tests/unit/controller/ResourceControllerTest.php ================================================ */ class ResourceControllerTest extends OntoWiki_Test_ControllerTestCase { public function setUp() { $this->setUpUnitTest(); } public function testExportActionReturnsCorrectContentTypeForTurtle() { $r = 'http://example.org/resource1'; $m = 'http://example.org/model1/'; $this->_storeAdapter->createModel($m); $this->request->setParam('r', $r); $this->request->setParam('m', $m); $this->request->setParam('f', 'turtle'); $this->dispatch('/resource/export'); $this->assertController('resource'); $this->assertAction('export'); $this->assertResponseCode(200); $this->assertHeaderContains('Content-Type', 'text/turtle'); } } ================================================ FILE: application/tests/unit/controller/_files/aksw.rss ================================================ blog.aksw.org http://blog.aksw.org The shared AKSW blog about our projects and the Semantic Web. Tue, 14 Dec 2010 16:02:49 +0000 http://wordpress.org/?v=2.1 en AKSW presents four papers at ISWC in Shanghai and wins Best Paper award http://blog.aksw.org/2010/aksw-presents-four-papers-at-iswc-in-shanghai-and-wins-best-paper-award/ http://blog.aksw.org/2010/aksw-presents-four-papers-at-iswc-in-shanghai-and-wins-best-paper-award/#comments Thu, 11 Nov 2010 10:16:10 +0000 Sören Auer Announcements OntoWiki Papers Erfurt ORE http://blog.aksw.org/2010/aksw-presents-four-papers-at-iswc-in-shanghai-and-wins-best-paper-award/ The AKSW research group is represented in the main ISWC conference programme this year with four papers. International Semantic Web Conference (ISWC) is the major international forum where the latest research results and technical innovations on all aspects of the Semantic Web are presented. Acceptance rates for the main conference programme were this year 20% for the research track and 26% for the In-Use track. AKSW’s presentations at ISWC in Shanghai include:

The paper titled Knowledge Engineering for Historians on the Example of the Catalogus Professorum Lipsiensis was awarded the best In-Use track paper award.

]]>
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/#comments Mon, 14 Jun 2010 14:55:47 +0000 Sebastian Tramp Software Releases OntoWikiOntoWikiRelease http://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.

More information about OntoWiki can be found at http://ontowiki.net. You can download OntoWiki in our google code file section.

Enhancements in this release include:

  • 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/#comments Fri, 09 Apr 2010 12:49:10 +0000 Sebastian Tramp Software Releases OntoWiki http://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/#comments Fri, 09 Apr 2010 11:35:53 +0000 ThomasRiechert Announcements Projects OntoWiki http://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/#comments Thu, 18 Mar 2010 11:45:06 +0000 ThomasRiechert Announcements Projects OntoWiki Events SoftWiki http://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): ?>

$value): ?>
================================================ FILE: application/views/templates/application/openid.phtml ================================================ * @version $Id: $ */ ?>
readonly ?> value="openid ?>" /> checked)): ?>
You can leave this blank.
You can leave this blank.
================================================ FILE: application/views/templates/application/register.phtml ================================================ * @author Philipp Frischmuth * @version $Id: userdetails.phtml 2917 2009-04-21 12:13:33Z norman.heino $ */ ?>
readonly ?> value="username ?>" />



================================================ FILE: application/views/templates/application/search.phtml ================================================ * @version $Id$ */ ?>

',$this->errorMsg); ?>

================================================ FILE: application/views/templates/application/userdetails.phtml ================================================ * @author Philipp Frischmuth * @version $Id: userdetails.phtml 3378 2009-06-24 14:09:30Z pfrischmuth $ */ ?>
isOpenIdUser) && $this->isOpenIdUser): ?>

userReadonly ?> value="username ?>" />



_('Change Password?') ?>
================================================ FILE: application/views/templates/application/webid.phtml ================================================ * @version $Id: $ */ ?>

Here is a list of FOAF+SSL services where you can create FOAF+SSL compliant certificates.

checked)): ?>


================================================ FILE: application/views/templates/error/404.phtml ================================================ */ ?> 404: Resource not found

Resource not found

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.

go back

================================================ FILE: application/views/templates/error/error.phtml ================================================ * @version $Id: error.phtml 3331 2009-06-16 19:25:43Z norman.heino $ */ ?> <?php echo $this->heading ?>

heading ?> code)): ?> (code ?>)

escape($this->errorText) ?> exceptionType)): ?>

exceptionType ?>

exceptionFile)): ?> exceptionFile ?> stacktrace)): ?>
stacktrace ?>

back  home

================================================ FILE: application/views/templates/index/index.phtml ================================================ * @version $Id: index.phtml 2327 2008-05-26 15:47:55Z norman.heino $ */ ?> headTitle()->append($this->_(' - Added by a Template With no Acces to ')) ?>

_('Bla bla, blub!') ?>

_('I am %1$s years old.'), $this->age) ?>

_('Click me!') ?> ================================================ FILE: application/views/templates/index/news.phtml ================================================ feed as $feedItem): ?>

title() ?>

description() ?>

================================================ FILE: application/views/templates/index/newsshort.phtml ================================================ rssData as $feedItem): ?>

================================================ FILE: application/views/templates/layouts/layout.phtml ================================================ * @author Michael Haschke * @version $Id: layout.phtml 4308 2009-10-14 15:13:51Z jonas.brekle@gmail.com $ */ ?> doctype('XHTML1_STRICT') ?> headTitle() ?> headMeta() ?> headLink() ?> partial('partials/meta.phtml') ?> has('jsonVars')): ?> has('metaDescription')){ ?> has('metaKeywords')){ ?> themeExtraStyles as $stylesheet_extra): ?> headStyle() ?> headScript() ?> inlineScript() ?>
setDefault($this->placeholder('main.window.title')); $title = $event->trigger(); ?>

preTabsContent)): ?>
preTabsContent; ?>
partial('partials/navigation.phtml', array('navigation' => OntoWiki::getInstance ()->getNavigation()->toArray())) ?> has('main.window.innerwindows')): ?>
has('formActionUrl') and $this->has('formMethod')): ?>
has('formName')) echo 'name="' . $this->formName . '"' ?> has('formId')) echo 'id="' . $this->formId . '"' ?> has('formEncoding')) echo 'enctype="' . $this->formEncoding . '"' ?> has('formClass')) echo 'class="' . $this->formClass . '"' ?>> has('redirectUrl')): ?> has('main.window.toolbar')): ?>
placeholder('main.window.toolbar') ?>
drawMessages() as $message): ?> partial('partials/message.phtml', array('message' => $message)) ?> layout()->content ?>
has('formActionUrl')): ?>
placeholder('main.window.innerwindows') ?>
has('formActionUrl') and $this->has('formMethod')): ?>
has('formName')) echo 'name="' . $this->formName . '"' ?> has('formEncoding')) echo 'enctype="' . $this->formEncoding . '"' ?> has('formClass')) echo 'class="' . $this->formClass . '"' ?>> has('main.window.toolbar')): ?>
placeholder('main.window.toolbar') ?>
drawMessages() as $message): ?> partial('partials/message.phtml', array('message' => $message)) ?> layout()->content ?> has('formActionUrl')): ?>
has('main.window.menu')): ?> partial('partials/statusbar.phtml', array('statusbar' => $this->placeholder('main.window.statusbar'))) ?>
placeholder('main.sidewindows') ?>
erfurt->getStore()->getQueryCount(); $time = (microtime(true) - REQUEST_START) * 1000; ?> ================================================ FILE: application/views/templates/model/config.phtml ================================================ * @version $Id: $ */ ?> modeluri)) { // this is the case e.g. when the model is not writable return; } ?>
_('Model Properties') ?>
readonly ?> value="modeluri ?>" />
readonly ?> value="baseuri ?>" />
isHidden ?> value="ishidden" name="ishidden"/>
isLarge ?> value="isLarge" name="isLarge"/>
useSysBase ?> useSysBaseDisabled ?> value="usesysbase" name="usesysbase"/>
_('Namespaces and Prefixes') ?>
prefixes as $prefix): ?> 'model', 'action' => 'config'), array('m')); $deleteUrl->setParam('delete_prefix', $prefix[0], true); ?>
Prefix Namespace
escape($prefix[0]) ?> escape($prefix[1]) ?> tonne
================================================ FILE: application/views/templates/model/create.phtml ================================================ formName == 'createmodel') : ?>
_('Basic information'); ?>

importActions) > 0) : ?>
_('Data import actions'); ?>

_('Please use one of these options to import data from various sources or with different tranformations:') ?>

importActions as $key => $action) : ?>
================================================ FILE: application/views/templates/model/info.phtml ================================================ values[$this->graphIri]) ? $this->values[$this->graphIri] : array(); ?>

modelTitle ?>

_('Comments, Descriptions and Notes') ?>

has('infoPredicates')): ?> infoPredicates as $uri => $predicate): ?>

_('There are no comments, descriptions or notes on this knowledge base.') ?>

partial('resource/properties.phtml',array( 'graphs' => $this->graphs, 'editableFlags' => $this->editableFlags, 'values' => $this->values, 'predicates' => $this->predicates, 'resourceUri' => $this->resourceIri, 'graphUri' => $this->graphIri, 'graphBaseUri' => $this->graphBaseIri, 'editable' => false, 'namespacePrefixes' => $this->namespacePrefixes )); //notice: ModelController (and the rest of this template) want Iri, //but ResourceController (and its template) want Uri ?>

_('Actions') ?>

has('showFoafLink') && $this->showFoafLink){ ?>open FOAF viewer
_('view all resources') ?> |  _('Jump to resource') ?>
================================================ FILE: application/views/templates/partials/contextmenu.phtml ================================================ * @author Michael Haschke */ ?>
    contextmenu as $menuKey => $menuItem): ?>

================================================ FILE: application/views/templates/partials/hierarchy_list.phtml ================================================ open): ?>
    ================================================ FILE: application/views/templates/partials/list.phtml ================================================ instances; $graph = $this->instances->getGraph(); $store = $this->instances->getStore(); // prepare namespaces try{ $namespacePrefixes = $graph->getNamespacePrefixes(); } catch (Exception $e){ $namespacePrefixes = array(); } $graphBase = $graph->getBaseUri(); if (!array_key_exists(OntoWiki_Utils::DEFAULT_BASE, $namespacePrefixes)) { $namespacePrefixes[OntoWiki_Utils::DEFAULT_BASE] = $graphBase; } //data for filter module $filter = $instances->getFilter(); $filter_js = json_encode(is_array($filter) ? $filter : array()); if (OntoWiki::getInstance()->extensionManager->isExtensionRegistered('filter')) { $this->headScript()->prependFile( OntoWiki::getInstance()->extensionManager->getComponentUrl('filter') .'resources/FilterAPI.js' ); } if ($instances->hasData()) { $instanceInfo = $instances->getResources(); if(!isset($this->other->disableValueQuery) || !$this->other->disableValueQuery){ $instanceData = $instances->getValues(); } else { $instanceData = array(); } if (!isset($this->other->statusBar) || $this->other->statusBar) { $statusBar = $this->placeholder('main.window.statusbar'); } else { $statusBar = null; } $itemsOnPage = count($instanceData); $propertyInfo = $instances->getShownProperties(); $time = (microtime(true) - $start) * 1000; $start = $instances->getOffset() + 1; $translate = OntoWiki::getInstance()->translate; $limit = $instances->getLimit(); $offset = $instances->getOffset(); if($limit != 0) { $page = ($offset / $limit) +1; } else { $page = 1; } $config = Erfurt_App::getInstance()->getConfig(); if($graph->getOption($config->sysont->properties->isLarge)) { if ($statusBar !== null) { $statusBar->append(OntoWiki_Pager::get( Erfurt_Store::COUNT_NOT_SUPPORTED, $limit, $itemsOnPage, $page, $this->listName)); } } else { $query = clone $instances->getResourceQuery(); $where = 'WHERE '.$query->getWhere(); try { $count = $store->countWhereMatches($graph->getModelIri(), $where, '?resourceUri', true); } catch (Erfurt_Store_Exception $e) { $count = Erfurt_Store::COUNT_NOT_SUPPORTED; } if ($statusBar !== null) { $statusBar->append(OntoWiki_Pager::get($count, $limit, $itemsOnPage, $page, $this->listName)); if ($count != Erfurt_Store::COUNT_NOT_SUPPORTED) { $results = $count > 1 ? $translate->translate('results') : $translate->translate('result'); $statusBar->append(sprintf($translate->translate('Search returned %1$d %2$s.'), $count, $results)); } } } if(!isset($count) || $count > 10 ){ if ($statusBar !== null) { $thisActionUrl = new OntoWiki_Url().'/'; $listLimit = $limit; $limit = '
      '; for($i = 10; $i <= 50; $i+=10){ $additionalClass = ($i == $listLimit)? 'selected ': ''; if($i == 10){ $limit .= '
    • Show me: '; }else{ $limit .= '
    • '; } $limit .= ''.$i.'
    • '; } $limit .= '
    '; $statusBar->append($limit); } } if (defined('_OWDEBUG')) { if ($statusBar !== null) { $statusBar->append(sprintf($translate->translate('Query execution took %1$d ms.'), $time)); } } } else { $instanceData = array(); $instanceInfo = array(); $propertyInfo = array(); } $this->headScript()->prependScript( 'var reloadUrl = "'. new OntoWiki_Url(array()). // url to reload -> without config params '"; var filtersFromSession = ' . $filter_js.'; var listName = "'.$this->listName.'";' ); //other contains template specific data $other = $this->other; $other->namespacePrefixes = $namespacePrefixes; $other->graphbase = $graphBase; //call the requested template echo $this->partial('partials/'.$this->mainTemplate.'.phtml', array( 'instances' => $instances, 'instanceData' => $instanceData, 'instanceInfo' => $instanceInfo, 'propertyInfo' => $propertyInfo, 'other' => $other, 'listName' => $this->listName, 'start' => $start ) ); ================================================ FILE: application/views/templates/partials/list_std_element.phtml ================================================ 'resource','action' => 'instances')); $url->setParam('init', true); // viewUrl will be used to generate links to object resources $viewUrl = new OntoWiki_Url(array('controller' => 'resource','action' => 'properties')); ?> instance['type'] == 'uri'){ //first table cell in row - instance title/label ?>
    instanceData[$this->instanceUri]) && isset($this->instanceData[$this->instanceUri]['__TYPE'])): //print the types/classes this instance belongs to ?> instanceData[$this->instanceUri]['__TYPE']) > 1): ?> instanceData[$this->instanceUri]['__TYPE']) ?> instanceData[$this->instanceUri]['__TYPE'] as $type): ?> ++$j ? ', ' : '') ?> instanceData[$this->instanceUri]['__TYPE'][0]['origvalue']; ?> instanceData[$this->instanceUri]['__TYPE'][0]['value']; /* title helper replaces the uri with a label here*/ ?> ' . $type . ''; ?> instance['title'] ?>
    Literal propertyInfo as $property): if($property['hidden']){continue;} //print all properties of that instance, each in a table cell ?> instanceUri, $this->instanceData) && array_key_exists($property['varName'], $this->instanceData[$this->instanceUri]) && !empty($this->instanceData[$this->instanceUri][$property['varName']])): if(count($this->instanceData[$this->instanceUri][$property['varName']]) > 1): ?>
      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) ?>
    • OW_SHOW_MAX ?>
    • OW_SHOW_MAX ?>
    instanceData[$this->instanceUri][$property['varName']]) && $this->instanceData[$this->instanceUri][$property['varName']][0]['url']): ?>
    setParam( 'r', $this->instanceData[$this->instanceUri][$property['varName']][0]['uri'] ); ?> instanceData[$this->instanceUri][$property['varName']][0]['value'] ?>
    instanceData[$this->instanceUri][$property['varName']][0]['value'] ?>
    ================================================ FILE: application/views/templates/partials/list_std_main.phtml ================================================ setEntry('Toggle show Permalink', "javascript:showPermaLink()"); $actionMenu->setEntry('Toggle show Resource Query', "javascript:showresQuery()"); $actionMenu->setEntry('Toggle show Value Query', "javascript:showvalQuery()"); $actions = new OntoWiki_Menu(); $actions->setEntry('View', $actionMenu); $this->placeholder('main.window.menu')->set($actions->toArray()); $instances = $this->instances; // get queries $resourceQuery = $instances->getResourceQuery(); $valueQuery = $instances->getQuery(); $permalink = $instances->getPermalink($this->listName); $config = Erfurt_App::getInstance()->getConfig(); $urlBase = $config->urlBase; $this->headScript()->prependScript( 'function showPermaLink(){$("#permalink").slideToggle(400);} function showresQuery(){$("#resQuery").slideToggle(400);} function showvalQuery(){$("#valQuery").slideToggle(400);} function changeSorting(n){ var mainInnerContent = $(n).parents(".innercontent"); mainInnerContent.addClass("is-processing"); mainInnerContent.load( reloadUrl+"", {"instancesconfig": $.toJSON({ sort : { "uri" : $(n).attr("p"), "asc" : $(n).hasClass("up") }}), "list":listName}, function(){ mainInnerContent.removeClass("is-processing"); $(".statustool li a").removeClass("selected"); $("body").trigger("ontowiki.resource-list.reloaded"); }); }' ); ?> instances->hasData()): ?> other->namespacePrefixes as $prefix => $namespace): ?> > propertyInfo)): ?> propertyInfo as $property): if($property['hidden']){continue;}?> start ?> instanceInfo as $instance){ //call subtemplate in a loop (for each instance a row) echo $this->partial('partials/list_std_element.phtml', array( 'instanceUri' => $instance['uri'], 'instance' => $instance, 'instanceData' => $this->instanceData, 'instanceInfo' => $this->instanceInfo, 'propertyInfo' => $this->propertyInfo, 'other' => $this->other, 'odd' => $odd, 'i' => $i ) ); $odd = !$odd; $i++; } ?>
    -1

    _('No matches.') ?>

    ================================================ FILE: application/views/templates/partials/menu.phtml ================================================ * @author Michael Haschke */ ?> menu as $name => $menu): ?>
  • _($name) ?>
  • partial('partials/menu.phtml', array('menu' => array($name => $menu->toArray(false, false)))) ?>
  • _($name) ?>
  • ================================================ FILE: application/views/templates/partials/message.phtml ================================================ * @author Michael Haschke */ ?>

    _($this->message->getText()) ?>

    ================================================ FILE: application/views/templates/partials/meta.phtml ================================================ has('update')): ?> placeholder('update') as $update): ?> ================================================ FILE: application/views/templates/partials/module.phtml ================================================ * @author Michael Haschke */ ?>
    cssId ? ' id="' . $this->cssId . '"' : '') ?>> content)): ?> content as $key => $value): ?>
    content ?>
    ================================================ FILE: application/views/templates/partials/navigation.phtml ================================================ * @author Michael Haschke */ ?> has('navigation')): ?>
      navigation as $key => $config): ?>
    1. _($config['name']) ?>
    ================================================ FILE: application/views/templates/partials/resultset.phtml ================================================ */ $resultCounter = 1; ?> data)){ ?> cssid)) echo "id=\"".$this->cssid."\"" ?>> has('caption')): ?> has('header')) $this->header = array_keys($this->data[0]); ?> header as $headerField): ?> data as $row): ?> ">
    caption;?>
    #
    escape($field); //literal } } else { $localpart = OntoWiki_Utils::getUriLocalPart($field["uri"]); ?>

    _('No matches.') ?>

    ================================================ FILE: application/views/templates/partials/statusbar.phtml ================================================ * @author Michael Haschke */ ?> has('statusbar')): ?>
    statusbar as $statusElement): ?>
    ================================================ FILE: application/views/templates/partials/table.phtml ================================================ */ if ($this->has('tableClass')) { echo '' . PHP_EOL; } else { echo '
    ' . PHP_EOL; } if ($this->has('caption')) { echo "" . PHP_EOL; } if ($this->has('header')) { echo '' . PHP_EOL; foreach ($this->header as $headerField) { echo "" . 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 '' . PHP_EOL; $c++; } echo '' . PHP_EOL; $r++; } echo '
    $this->caption
    $headerField
    '; } 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 ''; } else { // output only the value echo $this->escape($field); } echo '
    '; ================================================ FILE: application/views/templates/partials/toolbar.phtml ================================================ * @author Michael Haschke * @version $$ */ ?>
    lines)): ?> lines as $line): ?>
    tools)): ?> tools as $tool): ?>
    ================================================ FILE: application/views/templates/partials/window.phtml ================================================ * @author Michael Haschke */ ?>
    cssId ? ' id="' . $this->cssId . '"' : '') ?>> has('headinglevel')): ?> headinglevel ?> class="title">_($this->title) ?>headinglevel ?>>

    _($this->title) ?>

    has('innerwindows')): ?> messages)): ?> messages as $message): ?> partial('partials/message.phtml', array('message' => $message)) ?> has('navigation')): ?> partial('partials/navigation.phtml', array('navigation' => $this->navigation)) ?> has('innerwindows')): ?>
    messages)): ?> messages as $message): ?> partial('partials/message.phtml', array('message' => $message)) ?> content ?>
    innerwindows ?>
    content)): ?> content as $key => $value): ?>
    tools)): ?> partial('partials/toolbar.phtml', $this->tools) ?> content ?>
    has('menu')): ?> has('contextmenu')): ?>
    partial('partials/contextmenu.phtml', array('contextmenu' => $this->contextmenu)) ?>
    ================================================ FILE: application/views/templates/resource/instances.phtml ================================================ ================================================ FILE: application/views/templates/resource/properties.phtml ================================================ prePropertiesContent)): ?>
    prePropertiesContent; ?>
    has('predicates')): ?> graphs) ?> namespacePrefixes as $prefix => $namespace): ?> > predicates as $graph => $predicatesForGraph): ?> predicates[$graph]) > 0): /* has resource predicates from graph at all? */ ?> 1) || ($graph != $this->graphUri)): ?> $predicate): ?> predicates[$graph][$uri] ?>
    graphUri) ? $this->_('Imported from ') : '' ?> graphs[$graph] ?>
    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
      values[$graph][$uri] as $entry): ?>
    • xml:lang="" datatype="" >
    • [_('more') ?>]
    namespacePrefixes as $prefix => $namespace): ?> >

    _('No predicates found.') ?>

    ================================================ 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. (6 months ago by Natanael Arndt) * 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.'); ?>
    ================================================ FILE: extensions/account/templates/local.phtml ================================================



    _('Login') ?> showRegisterButton) : ?> _('Register') ?>
    ================================================ FILE: extensions/account/templates/mail/html/default.phtml ================================================

    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 ================================================

    _('Login') ?> showRegisterButton) : ?> _('Register') ?>
    ================================================ FILE: extensions/account/templates/webid.phtml ================================================
    _('Login') ?> showRegisterButton) : ?> _('Register') ?>
    ================================================ 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 ================================================
    showSearch) : ?>

    has('logo')): ?> <?php echo $this->logo_alt ?>

    ================================================ 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)): ?>
    _('If not provided a WebID will be generated.') ?>
    ================================================ FILE: extensions/auth/templates/auth/cert2.phtml ================================================ * @author Philipp Frischmuth * @version $Id: userdetails.phtml 2917 2009-04-21 12:13:33Z norman.heino $ */ ?> errorFlag)): ?>
    webid)): ?>

    depiction)): ?>



    ================================================ 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 //
  • SKOS Vocabulary
  • $('#lov-search-output').append( '
  • ' + '' + title + '' + '
  • ' ); } } else { $('#lov-search-output').append('
  • Sorry, nothing found
  • '); } $('#lov-search-input').removeClass('is-processing'); $('#lov-search-output').slideDown(); }; /* query the LOV endpoint with SPARQL and provide a callback */ var lovQuery = function (query, callback) { console.log(query); var parameters = { 'service-uri': "http://lov.okfn.org/endpoint/lov", query: query }; var ajaxOptions = { type: 'GET', timeout: 2000, url: 'http://cstadler.aksw.org/services/sparql-proxy.php', data: parameters, async: true, headers: { 'Accept': 'application/sparql-results+xml' }, success: flushSchemaTable }; $('#lov-search-input').addClass('is-processing'); $('#lov-search-output').hide().empty(); $.ajax(ajaxOptions); }; /* * here start the livequery assignments */ // click to add the data to other input fields lovSearchResults.livequery('click', function (event) { // query for data var prefix = $(event.target).data('prefix'), namespace = $(event.target).data('namespace'), title = $(event.target).text(); // do nothing on incomplete data if ((namespace !== undefined) && (prefix !== undefined)) { // fill and submit the modelconfig form if present var formModelConfig = $("form[name|='modelconfig']"); if (formModelConfig.length === 1) { formModelConfig.find("input[name|='new_prefix_prefix']").attr("value", prefix); formModelConfig.find("input[name|='new_prefix_namespace']").attr("value", namespace); formModelConfig.find("a.submit").trigger('click'); } // fill and submit the createmodel form if present var formCreateModel = $("form[name|='createmodel']"); if (formCreateModel.length === 1) { formCreateModel.find("input[name|='title']").attr("value", title); formCreateModel.find("input[name|='modeluri']").attr("value", namespace); formCreateModel.find("input[name|='importOptions']").attr("value", 'walkthrough'); $("#import-basicimporter-rdfweb").attr('checked', 'checked'); formCreateModel.find("a.submit").trigger('click'); } // fill and submit the Import from the web form if present if ($("#importdata").length === 1) { if ($("#location-input").length === 1) { $("#location-input").attr("value", namespace); $("form[name|='importdata'] a.submit").trigger('click'); } } } }); // do not search until user pressed enter lovSearchInput.livequery('keypress', function (event) { if ((event.which === 13) && (event.currentTarget.value !== '')) { // do search here var queryString = $(event.currentTarget).val(); $(event.currentTarget).val(''); lovQuery( 'PREFIX vann: ' + 'PREFIX voaf: ' + 'PREFIX dcterms: ' + 'SELECT DISTINCT ?prefix ?namespace ?title ' + 'WHERE{ ' + ' ?namespace a voaf:Vocabulary . ' + ' ?namespace dcterms:title ?title . ' + ' ?namespace vann:preferredNamespacePrefix ?prefix . ' + ' ?namespace ?property ?value . ' + ' FILTER regex(?value, ".*' + queryString + '.*", "i") }', flushSchemaTable ); return false; } if (event.which === 13) { return false; } return true; }); }); ================================================ FILE: extensions/basicimporter/SelectorModule.php ================================================ */ class SelectorModule extends OntoWiki_Module { public function getTitle() { return 'Select a Vocabulary'; } public function getContents() { $this->view->headScript()->appendFile( $this->_config->urlBase . 'extensions/basicimporter/SelectorModule.js' ); $data = array(); $content = $this->render('templates/basicimporter/search', $data); return $content; } } ================================================ FILE: extensions/basicimporter/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :extension . :extension a doap:Project ; doap:name "basicimporter" ; owconfig:privateNamespace ; owconfig:pluginEvent event:onProvideImportActions, event:onSetupStore ; owconfig:enabled "true"^^xsd:boolean ; rdfs:label "Basic Data Import Actions" ; doap:description "provides import from web an RDF files" ; owconfig:authorLabel "AKSW" ; doap:maintainer ; owconfig:templates "templates" ; owconfig:languages "languages" ; doap:release :v1-0 ; owconfig:hasModule :Selector . :Selector a owconfig:Module ; owconfig:priority "19" ; rdfs:label "LOV Selector" ; owconfig:context "main.window.basicimporter.rdfwebimport", "main.window.modelcreate", "main.window.modelconfig". :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: extensions/basicimporter/languages/basicimporter-de.csv ================================================ LovBySearch;Suche LovByPrefix;Präfix LovByCategory;Kategorie ================================================ FILE: extensions/basicimporter/languages/basicimporter-en.csv ================================================ LovBySearch;Search LovByPrefix;Prefix LovByCategory;Category ================================================ FILE: extensions/basicimporter/templates/basicimporter/category.phtml ================================================

    The Linked Open Vocabulary (LOV) repository categorizes over 300 Semantic Web ontologies

    Not implemented yet

    ================================================ FILE: extensions/basicimporter/templates/basicimporter/prefix.phtml ================================================

    The prefix.cc service allows for prefix searches.

    Not implemented yet

    ================================================ FILE: extensions/basicimporter/templates/basicimporter/rdfpaster.phtml ================================================
    _('Paste Source') ?>


    ================================================ FILE: extensions/basicimporter/templates/basicimporter/rdfupload.phtml ================================================
    _('Upload a File') ?>


    ================================================ FILE: extensions/basicimporter/templates/basicimporter/rdfwebimport.phtml ================================================
    _('Import From the Web') ?>

    _('Enter the URL where the model should be downloaded from. If you leave the field empty the model URI will be used.') ?>


    ================================================ FILE: extensions/basicimporter/templates/basicimporter/search.phtml ================================================

    Find vocabularies by searching the Linked Open Vocabularies (LOV) repository.

    ================================================ FILE: extensions/bookmarklet/BookmarkletModule.php ================================================ * @author Sebastian Tramp * @copyright Copyright (c) 2012, {@link http://aksw.org AKSW} * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL) */ class BookmarkletModule extends OntoWiki_Module { public function getTitle() { return 'Bookmarklet'; } public function getContents() { $this->view->infoMessage = 'Use this Bookmarklet to add content to this Knowledge Base.'; $this->view->rdfAuthorBase = $this->_config->libraryUrlBase . 'RDFauthor/'; $this->view->defaultGraph = (string)OntoWiki::getInstance()->selectedModel; $this->view->defaultUpdateService = $this->_config->urlBase . 'update/'; $this->view->defaultQueryService = $this->_config->urlBase . 'sparql/'; $this->view->ontoWikiUrl = $this->_config->urlBase; $frontController = Zend_Controller_Front::getInstance(); $request = $frontController->getRequest(); return $this->render('bookmarklet'); } public function shouldShow() { // do not show if model is not writeable if ($this->_owApp->selectedModel->isEditable()) { return true; } else { return false; } } } ================================================ FILE: extensions/bookmarklet/bookmarklet.phtml ================================================ */ /** * OntoWiki bookmarklet module template * * @author Sebastian Dietzold */ ?> has('warningMessage')): ?>

    warningMessage ?>

    has('infoMessage')): ?>

    infoMessage ?>

    ================================================ FILE: extensions/bookmarklet/default.ini ================================================ enabled = false name = "RDFauthor Bookmarklet" caching = no priority = 19 contexts[] = "main.window.modelinfo" description = "extract rdfa from websites, import to ontowiki, done with RDFauthor delivered in a bookmarklet." author = "AKSW" authorUrl = "http://aksw.org" [private] ================================================ FILE: extensions/bookmarklet/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :bookmarklet . :bookmarklet a doap:Project ; doap:name "bookmarklet" ; owconfig:privateNamespace ; owconfig:enabled "false"^^xsd:boolean ; rdfs:label "RDFauthor Bookmarklet" ; doap:description "extract rdfa from websites, import to ontowiki, done with RDFauthor delivered in a bookmarklet." ; owconfig:authorLabel "AKSW" ; doap:maintainer ; owconfig:hasModule :Default . :Default a owconfig:Module ; rdfs:label "Default" ; owconfig:caching "false"^^xsd:boolean ; owconfig:priority "19" ; owconfig:context "main.window.modelinfo" . :bookmarklet doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: extensions/ckan/CkanController.php ================================================ store = $this->_owApp->erfurt->getStore(); $this->_config = $this->_owApp->config; $this->response = Zend_Controller_Front::getInstance()->getResponse(); $this->request = Zend_Controller_Front::getInstance()->getRequest(); } /** * search GUI to import CKAN packages into ontowiki * TODO: finish :) */ public function browserAction() { $t = $this->_owApp->translate; $this->view->placeholder('main.window.title')->set($t->_('CKAN Package Browser')); $this->addModuleContext('main.window.ckan.browser'); OntoWiki::getInstance()->getNavigation()->disableNavigation(); echo "not finished yet"; return; } /** * forwards to the CKAN registration page with some prefilled values */ public function registerAction() { // this action needs no view $this->_helper->viewRenderer->setNoRender(); // disable layout $this->_helper->layout()->disableLayout(); // m (model) 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; } // get model URI / resource and load description $resourceUri = (string)$model; $resource = new Erfurt_Rdf_Resource($resourceUri, $model); $description = $resource->getDescription(); $description = $description[$resourceUri]; // fill CKAN parameter $parameter = array(); $parameter['title'] = $model->getTitle(); $parameter['url'] = $resourceUri; // go through the model info properties and use the first value as // notes value for ckan $infoProperties = $this->_config->descriptionHelper->properties; foreach ($infoProperties as $infoProperty) { if (!isset($parameter['description'])) { if (isset($description[$infoProperty][0]['value'])) { $parameter['notes'] = $description[$infoProperty][0]['value']; } } } // build GET URI from the parameter array to redirect $getparams = '?'; foreach ($parameter as $key => $value) { $getparams .= '&' . $key . '=' . urlencode($value); } $redirectUrl = $this->registerBaseUrl . $getparams; // redirect to CKANs dataset registration page $this->_response->setRedirect($redirectUrl, $code = 302); } } ================================================ FILE: extensions/ckan/CkanHelper.php ================================================ resource; $baseUrl = OntoWiki::getInstance()->config->urlBase; $extensionManager = OntoWiki::getInstance()->extensionManager; // do NOT create the menu entry ... switch (true) { // ... for resources case (!$event->isModel): // ... for localhost models (can't be registered at CKAN) case (substr_count($modelUri, 'http://localhost') > 0): // ... if the model is not part of the base url (no Linked Data) case (substr_count($modelUri, $baseUrl) !== 1) : // ... if we do not have a linked data server online case (!$extensionManager->isExtensionRegistered('linkeddataserver')): return; } // finally, create the holy menu entry and PREPEND it on top of the menu $url = new OntoWiki_Url( array('controller' => 'ckan', 'action' => 'register'), array('m') ); $url->setParam('m', $modelUri); $event->menu->prependEntry('Register Knowledge Base @ CKAN', (string)$url); } } ================================================ FILE: extensions/ckan/default.ini ================================================ enabled = false name = "CKAN Integration" description = "allows for registration of CKAN datasets from your OntoWiki instance" author = "Sebastian Tramp" authorUrl = "http://sebastian.tramp.name" templates = "templates" languages = "languages" helperEvents[] = "onCreateMenu" [private] features.registration = enabled ================================================ FILE: extensions/ckan/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :ckan . :ckan a doap:Project ; doap:name "ckan" ; owconfig:privateNamespace ; owconfig:enabled "false"^^xsd:boolean ; rdfs:label "CKAN Integration" ; doap:description "allows for registration of CKAN datasets from your OntoWiki instance" ; owconfig:authorLabel "Sebastian Tramp" ; doap:maintainer ; owconfig:templates "templates" ; owconfig:languages "languages" ; owconfig:helperEvent event:onCreateMenu ; owconfig:config [ a owconfig:Config; owconfig:id "features"; :registration "enabled" ] ; doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: extensions/ckan/templates/ckan/browser.phtml ================================================

    Search for a CKAN datasets and upload it to a new Knowledge Base

    data)) : ?>
      data as $package) : ?>
    • title ?>
    ================================================ FILE: extensions/community/CommentModule.php ================================================ * @author Sebastian Tramp * @author Natanael Arndt */ class CommentModule extends OntoWiki_Module { public function init() { } public function getTitle() { return 'Latest Comments'; } public function getContents() { $content = ''; // comment form part if ((isset($this->_owApp->selectedModel)) && ($this->_owApp->erfurt->getAc()->isModelAllowed('edit', $this->_owApp->selectedModel)) ) { $limit = $this->_privateConfig->limit; $actionUrl = new OntoWiki_Url(array('controller' => 'community', 'action' => 'comment'), array()); $listUrl = new OntoWiki_Url(array('controller' => 'community', 'action' => 'list'), array()); $listUrl->setParam('climit', $limit, true); $this->view->actionUrl = (string)$actionUrl; $this->view->listUrl = (string)$listUrl; $this->view->context = $this->getContext(); $content = $this->render('templates/comment'); } if ($this->getContext() != 'main.window.community') { $helper = $this->_owApp->extensionManager->getComponentHelper('community'); $comments = $helper->getList($this->view); if ($comments === null) { $this->view->infomessage = 'There are no discussions yet.'; } else { $this->view->comments = $comments; } $content .= $this->render('templates/lastcomments'); } return $content; } } ================================================ FILE: extensions/community/CommunityController.php ================================================ * @author Jonas Brekle * @author Natanael Arndt */ class CommunityController extends OntoWiki_Controller_Component { /** * list comments */ public function listAction() { $translate = $this->_owApp->translate; $singleResource = true; if ($this->_request->getParam('mode') === 'multi') { $windowTitle = $translate->_('Discussion about elements of the list'); $singleResource = false; } else { $resource = $this->_owApp->selectedResource; if ($resource->getTitle()) { $title = $resource->getTitle(); } else { $title = OntoWiki_Utils::contractNamespace($resource->getIri()); } $windowTitle = sprintf($translate->_('Discussion about %1$s'), $title); } $this->addModuleContext('main.window.community'); $this->view->placeholder('main.window.title')->set($windowTitle); $limit = $this->_request->getParam('climit'); if ($limit === null) { $limit = 10; } $helper = $this->_owApp->extensionManager->getComponentHelper('community'); $comments = $helper->getList($this->view, $singleResource, $limit); if ($comments === null) { $this->view->infomessage = 'There are no discussions yet.'; } else { $this->view->comments = $comments; } } /** * save a comment */ public function commentAction() { if (!$this->_owApp->selectedModel->isEditable()) { throw new Erfurt_Ac_Exception("Access control violation. Model not editable."); } $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout()->disableLayout(); $user = $this->_owApp->getUser()->getUri(); $date = date('c'); // xsd:datetime $resource = (string)$this->_owApp->selectedResource; $aboutProperty = $this->_privateConfig->about->property; $creatorProperty = $this->_privateConfig->creator->property; $commentType = $this->_privateConfig->comment->type; $contentProperty = $this->_privateConfig->content->property; $dateProperty = $this->_privateConfig->date->property; $content = $this->getParam('c'); if (!empty($content)) { // make URI $commentUri = $this->_owApp->selectedModel->createResourceUri('Comment'); // preparing versioning $versioning = $this->_erfurt->getVersioning(); $actionSpec = array(); $actionSpec['type'] = 110; $actionSpec['modeluri'] = (string)$this->_owApp->selectedModel; $actionSpec['resourceuri'] = $commentUri; $versioning->startAction($actionSpec); // insert comment $this->_owApp->selectedModel->addStatement( $commentUri, $aboutProperty, array('value' => $resource, 'type' => 'uri') ); $this->_owApp->selectedModel->addStatement( $commentUri, EF_RDF_TYPE, array('value' => $commentType, 'type' => 'uri') ); $this->_owApp->selectedModel->addStatement( $commentUri, $creatorProperty, array('value' => (string)$user, 'type' => 'uri') ); $this->_owApp->selectedModel->addStatement( $commentUri, $dateProperty, array( 'value' => $date, 'type' => 'literal', 'datatype' => EF_XSD_NS . 'dateTime' ) ); $this->_owApp->selectedModel->addStatement( $commentUri, $contentProperty, array( 'value' => $content, 'type' => 'literal' ) ); // stop Action $versioning->endAction(); } } /** * rate a resource */ public function rateAction() { if (!$this->_owApp->selectedModel->isEditable()) { require_once 'Erfurt/Ac/Exception.php'; throw new Erfurt_Ac_Exception("Access control violation. Model not editable."); } $user = $this->_owApp->getUser()->getUri(); $date = date('rating'); // xsd:datetime $resource = (string)$this->_owApp->selectedResource; $aboutProperty = $this->_privateConfig->about->property; $creatorProperty = $this->_privateConfig->creator->property; $ratingType = $this->_privateConfig->rating->type; $noteProperty = $this->_privateConfig->note->property; $dateProperty = $this->_privateConfig->date->property; //get rating Value $ratingValue = $this->getParam('rating'); if (!empty($ratingValue)) { $query = new Erfurt_Sparql_SimpleQuery(); $model = OntoWiki::getInstance()->selectedModel; //query rating and creator of rating $query->setProloguePart( ' prefix rdf: prefix ns0: prefix ns1: ' ); $query->setSelectClause('SELECT *'); $query->setWherePart( 'where { ?rating rdf:type ns1:Poll. ?rating ns0:about <' . $this->_owApp->selectedResource . '>. ?rating ns0:has_creator ?creator}' ); $results = $model->sparqlQuery($query); if ($results) { $creatorExists = false; foreach ($results as $result) { if ((string)$user == $result['creator']) { $creatorExists = true; $ratingNote = $result['rating']; break; } } if ($creatorExists) { $this->_owApp->selectedModel->deleteMatchingStatements($ratingNote, null, null, array()); } } // make URI $ratingNoteUri = $this->_owApp->selectedModel->createResourceUri('Rating'); // preparing versioning $versioning = $this->_erfurt->getVersioning(); $actionSpec = array(); $actionSpec['type'] = 110; $actionSpec['modeluri'] = (string)$this->_owApp->selectedModel; $actionSpec['resourceuri'] = $ratingNoteUri; $versioning->startAction($actionSpec); // create namespaces (todo: this should be based on used properties) $this->_owApp->selectedModel->getNamespacePrefix('http://rdfs.org/sioc/ns#'); $this->_owApp->selectedModel->getNamespacePrefix('http://rdfs.org/sioc/types#'); $this->_owApp->selectedModel->getNamespacePrefix('http://localhost/OntoWiki/Config/'); // insert rating $this->_owApp->selectedModel->addStatement( $ratingNoteUri, $aboutProperty, array('value' => $resource, 'type' => 'uri') ); $this->_owApp->selectedModel->addStatement( $ratingNoteUri, EF_RDF_TYPE, array('value' => $ratingType, 'type' => 'uri') ); $this->_owApp->selectedModel->addStatement( $ratingNoteUri, $creatorProperty, array('value' => (string)$user, 'type' => 'uri') ); $this->_owApp->selectedModel->addStatement( $ratingNoteUri, $dateProperty, array( 'value' => $date, 'type' => 'literal', 'datatype' => EF_XSD_NS . 'dateTime' ) ); $this->_owApp->selectedModel->addStatement( $ratingNoteUri, $noteProperty, array( 'value' => $ratingValue, 'type' => 'literal' ) ); $cache = $this->_erfurt->getQueryCache(); $ret = $cache->cleanUpCache(array('mode' => 'uninstall')); } // stop Action $versioning->endAction(); } } ================================================ FILE: extensions/community/CommunityHelper.php ================================================ getParam('mode') == 'multi' if tab should also be displayed for * multiple resources/lists ($request->getActionName() == 'instances') * And set 'mode' => 'multi' to tell the controller the multi mode * * Multi mode was disabled because it doesn't seam to work */ $owApp = OntoWiki::getInstance(); if ($owApp->lastRoute == 'properties' && $owApp->selectedResource != null) { $owApp->getNavigation()->register( 'community', array( 'controller' => 'community', 'action' => 'list', 'name' => 'Community', 'mode' => 'single', 'priority' => 50 ) ); } } public function getList($view, $singleResource = true, $limit = null) { $store = $this->_owApp->erfurt->getStore(); $graph = $this->_owApp->selectedModel; $resource = $this->_owApp->selectedResource; $aboutProperty = $this->_privateConfig->about->property; $creatorProperty = $this->_privateConfig->creator->property; $commentType = $this->_privateConfig->comment->type; $contentProperty = $this->_privateConfig->content->property; $dateProperty = $this->_privateConfig->date->property; if ($limit === null) { $limit = $this->_privateConfig->limit; } // get all resource comments // Loading data for list of saved queries $listHelper = Zend_Controller_Action_HelperBroker::getStaticHelper('List'); $list = new OntoWiki_Model_Instances($store, $graph, array()); $list->addTypeFilter($commentType, 'searchcomments'); $list->addShownProperty($aboutProperty, "about", false, null, false); $list->addShownProperty($creatorProperty, "creator", false, null, false); $list->addShownProperty($contentProperty, "content", false, null, false); $list->addShownProperty($dateProperty, "date", false, null, false); $list->setLimit($limit); $list->setOrderProperty($dateProperty, false); if ($singleResource) { $list->addTripleFilter( array( new Erfurt_Sparql_Query2_Triple( $list->getResourceVar(), new Erfurt_Sparql_Query2_IriRef($aboutProperty), new Erfurt_Sparql_Query2_IriRef((string)$resource) ) ) ); } else { // doesn't work $list->addShownProperty($aboutProperty, "about", false, null, false); $instances = $listHelper->getList('instances'); $query = clone $instances->getResourceQuery(); $resourceVar = $instances->getResourceVar(); $vars = $query->getWhere()->getVars(); foreach ($vars as $var) { if ($var->getName() == $resourceVar->getName()) { $var->setName('listresource'); } } $elements = $query->getWhere()->getElements(); //link old list to elements of the community-list $elements[] = new Erfurt_Sparql_Query2_Triple( $list->getResourceVar(), new Erfurt_Sparql_Query2_IriRef($aboutProperty), $var ); $list->addTripleFilter($elements, "listfilter"); } $listName = "community"; $other = new stdClass(); $other->singleResource = $singleResource; $other->statusBar = false; if ($list->hasData()) { return $listHelper->addListPermanently( $listName, $list, $view, 'list_community_main', $other, true ); } else { return null; } } public function getMultiList() { $this->store = $this->_owApp->erfurt->getStore(); $this->model = $this->_owApp->selectedModel; /* prepare schema elements */ // TODO: This should be used from the CommunityController $aboutProperty = $this->_privateConfig->about->property; $creatorProperty = $this->_privateConfig->creator->property; $commentType = $this->_privateConfig->comment->type; $contentProperty = $this->_privateConfig->content->property; $dateProperty = $this->_privateConfig->date->property; $realLimit = $this->_privateConfig->limit + 1; // used for query to check for "more" // get the latest comments $commentSparql = 'SELECT DISTINCT ?resource ?author ?comment ?content ?date #?alabel WHERE { ?comment <' . $aboutProperty . '> ?resource. ?comment a <' . $commentType . '>. ?comment <' . $creatorProperty . '> ?author. ?comment <' . $contentProperty . '> ?content. ?comment <' . $dateProperty . '> ?date. } ORDER BY DESC(?date) LIMIT ' . $realLimit; $query = Erfurt_Sparql_SimpleQuery::initWithString($commentSparql); return $this->model->sparqlQuery($query); } } ================================================ FILE: extensions/community/LastchangesModule.php ================================================ */ class LastchangesModule extends OntoWiki_Module { public function init() { // enabling versioning $this->versioning = $this->_erfurt->getVersioning(); if (!$this->versioning instanceof Erfurt_Versioning) { return; } if (!$this->versioning->isVersioningEnabled()) { $this->view->warningmessage = 'Versioning/history is currently disabled. This means, you can not see the latest changes.'; } else { // The system config is used to get the user title // TODO: How can switch from ACL to Non-ACL use? $this->systemModel = new Erfurt_Rdf_Model('http://localhost/OntoWiki/Config/', 'http://localhost/OntoWiki/Config/'); if ($this->getContext() == "main.window.dashmodelinfo") { $this->user = $this->_erfurt->getAuth()->getIdentity()->getUri(); $this->results = $this->versioning->getHistoryForUserDash($this->user); } else { $this->model = $this->_owApp->selectedModel; $this->results = $this->versioning->getConciseHistoryForGraph($this->model->getModelIri()); } } } public function getTitle() { return 'Latest Changes'; } public function shouldShow() { if (!$this->versioning instanceof Erfurt_Versioning) { return false; } return true; } public function getContents() { $url = new OntoWiki_Url(array('route' => 'properties'), array('r')); $changes = array(); if ($this->results) { foreach ($this->results as $change) { if ($this->getContext() == "main.window.dashmodelinfo") { //id, resource, tstamp, action_type $change['useruri'] = $this->user; $this->model = null; } if (Erfurt_Uri::check($change['resource'])) { $change['aresource'] = new OntoWiki_Resource((string)$change['useruri'], $this->systemModel); if ($change['aresource']->getTitle()) { $change['author'] = $change['aresource']->getTitle(); } else { $change['author'] = OntoWiki_Utils::getUriLocalPart($change['aresource']); } $url->setParam('r', (string)$change['aresource'], true); $change['ahref'] = (string)$url; $url->setParam('r', (string)$change['resource'], true); $change['rhref'] = (string)$url; $change['resource'] = new OntoWiki_Resource((string)$change['resource'], $this->model); if ($change['resource']->getTitle()) { $change['rname'] = $change['resource']->getTitle(); } else { $change['rname'] = OntoWiki_Utils::contractNamespace($change['resource']->getIri()); } $changes[] = $change; } } } if (empty($changes)) { $this->view->infomessage = 'There are no changes yet.'; } else { $this->view->changes = $changes; } return $this->render('templates/lastchanges'); } } ================================================ FILE: extensions/community/RatingModule.php ================================================ 'community', 'action' => 'rate'), array()); $this->view->actionUrl = (string)$url; $query = new Erfurt_Sparql_SimpleQuery(); $model = new OntoWiki_Model(Erfurt_App::getInstance()->getStore(), $this->_owApp->selectedModel); //query ratings for the current resource $query->setProloguePart( 'prefix rdf: prefix ns0: prefix ns1: prefix terms: ' ); $query->setSelectClause('SELECT *'); $query->setWherePart( 'where { ?rating rdf:type ns1:Poll. ?rating ns0:about <' . $this->_owApp->selectedResource . '>. ?rating ns0:note ?note. ?rating ns0:has_creator ?creator}' ); $results = $this->_store->sparqlQuery($query); $ratingArray = Array(); $user = (string)$this->_owApp->getUser()->getUri(); $creator = '0'; $creatorNote = '0'; foreach ($results as $result) { $ratingArray[] = (double)$result['note']; if ($user == $result['creator']) { $creator = '1'; $creatorNote = (double)$result['note']; } } $rating = '0'; $ratingvalue = '0'; if (count($ratingArray) != 0) { $ratingvalue = round(array_sum($ratingArray) / count($ratingArray), 2); $rating = round(array_sum($ratingArray) / count($ratingArray) * 2 - 1, 0); } $ratingJs = 'var rating = ' . ($rating) . '; var count =' . count($ratingArray) . '; var creator =' . $creator . '; var creatorNote =' . ($creatorNote - 1) . '; var ratingValue =' . $ratingvalue . ';'; // append Java Scripts and Style Sheets $this->view->headScript()->appendScript($ratingJs); $this->view->headScript()->appendFile($this->_config->urlBase . 'extensions/modules/rating/jquery.MetaData.js'); $this->view->headScript()->appendFile($this->_config->urlBase . 'extensions/modules/rating/jquery.rating.js'); $this->view->headScript()->appendFile( $this->_config->urlBase . 'extensions/modules/rating/jquery.rating.pack.js' ); $this->view->headScript()->appendFile($this->_config->urlBase . 'extensions/modules/rating/rating.js'); $this->view->headLink()->appendStylesheet( $this->_config->urlBase . 'extensions/modules/rating/jquery.rating.css' ); $this->view->count = count($ratingArray); $this->view->rating = $ratingvalue; $content = $this->render('templates/rating'); return $content; } public function shouldShow() { // show only if enabled in private config if ($this->_privateConfig->enableRating == false) { return false; } // the rating action is displayed only for registered users // and if set in the module.ini file only for predefined resources if ($this->_owApp->getUser()->getUsername() == 'Anonymous' || !$this->typeAllowed()) { return false; } else { return true; } } private function typeAllowed() { if ($this->_privateConfig->ratingClass) { $classArray = $this->_privateConfig->ratingClass->toArray(); $store = $this->_owApp->erfurt->getStore(); $resource = $this->_owApp->selectedResource; $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT *')->setWherePart( 'WHERE { <' . $resource . '> <' . EF_RDF_TYPE . '> ?type }' ); $results = $store->sparqlQuery($query); if (in_array($results[0]['type'], $classArray)) { return true; } else { return false; } } else { return true; } } } ================================================ FILE: extensions/community/default.ini ================================================ ;; ; Basic component configuration ;; enabled = true templates = "templates" languages = "languages/" action = list name = "Community" description = "rate and comment on resources." author = "AKSW" authorUrl = "http://aksw.org" modules.comment.priority = 19 modules.comment.name = "Comment" modules.comment.contexts.0 = "main.window.community" modules.lastchanges.priority = 18 modules.lastchanges.name = "Last Changes" modules.lastchanges.contexts.0 = "main.window.modelinfo" modules.lastchanges.contexts.1 = "main.window.dashmodelinfo" modules.lastcomments.priority = 15 modules.lastcomments.name = "Last Comments" modules.lastcomments.contexts.0 = "main.window.modelinfo" modules.lastcomments.contexts.1 = "main.window.dashmodelinfo" modules.rating.title = "Rating" modules.rating.caching = no modules.rating.priority = 20 modules.rating.contexts.0 = "main.window.properties" ;; ; Component's private configuration ; Anything set below will be available within the component ($this->_privateConfig->key) ;; [private] enableRating = false ;-----------------------------------------------------------------------------; ; Properties and types used for comments and ratings. ; ;-----------------------------------------------------------------------------; about.property = "http://rdfs.org/sioc/ns#about" ; comment about resource creator.property = "http://rdfs.org/sioc/ns#has_creator" ; comment has_creator user comment.type = "http://rdfs.org/sioc/types#Comment" ; comment rdf:type Comment content.property = "http://rdfs.org/sioc/ns#content" ; comment content "literal" date.property = "http://purl.org/dc/terms/created" ; comment created_at "2008-03-07"^^xsd:date rating.type = "http://rdfs.org/sioc/types#Poll" ; rating rdf:type Poll note.property = "http://rdfs.org/sioc/ns#note" ; rating note "note" ================================================ FILE: extensions/community/default.n3 ================================================ @prefix foaf: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix event: . @prefix : . @prefix xsd: . <> foaf:primaryTopic :community . :community a doap:Project; doap:name "Community"; doap:description "rate and comment on resources."; doap:maintainer ; owconfig:enabled "true"^^xsd:boolean; owconfig:templates "templates"; owconfig:languages "languages/"; owconfig:action "list"; owconfig:hasModule :Comments, :LastChanges, :LastComments, :Rating; owconfig:privateNamespace . :Comments a owconfig:Module; rdfs:label "Comment"; owconfig:priority 19; owconfig:context . :LastChanges a owconfig:Module; rdfs:label "Last Changes"; owconfig:priority 18; owconfig:context ; owconfig:context . :LastComments a owconfig:Module; rdfs:label "Last Comments"; owconfig:priority 15; owconfig:context ; owconfig:context . :Rating a owconfig:Module; rdfs:label "Rating"; owconfig:caching "false"^^xsd:boolean; owconfig:priority 20; owconfig:context . :community :enableRating "false"^^xsd:boolean; owconfig:config [ # about.property = "http://rdfs.org/sioc/ns#about" ; comment about resource a owconfig:Config; owconfig:id "about"; rdfs:comment "comment about resource"; :property ]; owconfig:config [ # creator.property = "http://rdfs.org/sioc/ns#has_creator" ; comment has_creator user owconfig:id "creator"; rdfs:comment "comment has_creator user"; :property ]; # comment.type = "http://rdfs.org/sioc/types#Comment" ; comment rdf:type Comment owconfig:config [ owconfig:id "comment"; rdfs:comment "comment rdf:type Comment"; :type ]; owconfig:config [ # content.property = "http://rdfs.org/sioc/ns#content" ; comment content "literal" owconfig:id "content"; rdfs:comment "comment content literal"; :property ]; owconfig:config [ # date.property = "http://purl.org/dc/terms/created" ; comment created_at "2008-03-07"^^xsd:date owconfig:id "date"; rdfs:comment "comment created_at '2008-03-07'^^xsd:date"; :property ]; owconfig:config [ # rating.type = "http://rdfs.org/sioc/types#Poll" ; rating rdf:type Poll owconfig:id "rating"; rdfs:comment "rating rdf:type Poll"; :type ]; owconfig:config [ # note.property = "http://rdfs.org/sioc/ns#note" ; rating note "note" owconfig:id "note"; rdfs:comment "rating note literal"; :property ]. ================================================ FILE: extensions/community/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :community . :community a doap:Project ; doap:name "community" ; owconfig:privateNamespace ; owconfig:enabled "true"^^xsd:boolean ; owconfig:templates "templates" ; owconfig:languages "languages/" ; owconfig:defaultAction "list" ; rdfs:label "Community" ; doap:description "rate and comment on resources." ; owconfig:authorLabel "AKSW" ; doap:maintainer ; owconfig:hasModule :Comment . :Comment a owconfig:Module ; owconfig:priority "19" ; rdfs:label "Comment" ; owconfig:context "main.window.modelinfo" ; owconfig:context "main.window.dashmodelinfo" ; owconfig:context "main.window.community" ; owconfig:context "main.window.properties" . :community owconfig:hasModule :Lastchanges . :Lastchanges a owconfig:Module ; owconfig:priority "18" ; rdfs:label "Last Changes" ; owconfig:context "main.window.modelinfo" ; owconfig:context "main.window.dashmodelinfo" . :community owconfig:hasModule :Rating . :Rating a owconfig:Module ; rdfs:label "Rating" ; owconfig:caching "false"^^xsd:boolean ; owconfig:priority "20" ; owconfig:context "main.window.properties" . :community :enableRating "false"^^xsd:boolean ; :limit "5"^^xsd:int ; owconfig:config [ a owconfig:Config; owconfig:id "about"; :property ]; owconfig:config [ a owconfig:Config; owconfig:id "creator"; :property ]; owconfig:config [ a owconfig:Config; owconfig:id "comment"; :type ]; owconfig:config [ a owconfig:Config; owconfig:id "content"; :property ]; owconfig:config [ a owconfig:Config; owconfig:id "date"; :property ]; owconfig:config [ a owconfig:Config; owconfig:id "rating"; :type ]; owconfig:config [ a owconfig:Config; owconfig:id "note"; :property ] . :community doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: extensions/community/insert.sparql ================================================ insert into graph { . a . . "Good idea.". "2008-12-09T02:04:34"^^xsd:dateTime. } ================================================ FILE: extensions/community/jquery.MetaData.js ================================================ /* * Metadata - jQuery plugin for parsing metadata from elements * * Copyright (c) 2006 John Resig, Yehuda Katz, Jrn Zaefferer, Paul McLanahan * * 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$ * */ /** * Sets the type of metadata to use. Metadata is encoded in JSON, and each property * in the JSON will become a property of the element itself. * * There are three supported types of metadata storage: * * attr: Inside an attribute. The name parameter indicates *which* attribute. * * class: Inside the class attribute, wrapped in curly braces: { } * * elem: Inside a child element (e.g. a script tag). The * name parameter indicates *which* element. * * The metadata for an element is loaded the first time the element is accessed via jQuery. * * As a result, you can define the metadata type, use $(expr) to load the metadata into the elements * matched by expr, then redefine the metadata type and run another $(expr) for other elements. * * @name $.metadata.setType * * @example

    This is a p

    * @before $.metadata.setType("class") * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" * @desc Reads metadata from the class attribute * * @example

    This is a p

    * @before $.metadata.setType("attr", "data") * @after $("#one").metadata().item_id == 1; $("#one").metadata().item_label == "Label" * @desc Reads metadata from a "data" attribute * * @example

    This is a p

    * @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 ================================================

    context == 'main.window.community') : ?> add comment icon _('Post Comment') ?>

    ================================================ FILE: extensions/community/templates/community/list.phtml ================================================ has('infomessage')): ?>

    _($this->infomessage) ?>

    has('comments')): ?>
    comments; ?>
    ================================================ FILE: extensions/community/templates/lastchanges.phtml ================================================ * @copyright Copyright (c) 2009, {@link http://aksw.org AKSW} * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL) * @version $Id: $ */ ?> has('warningmessage')): ?>

    warningmessage ?>

    has('infomessage')): ?>

    infomessage ?>

    has('changes')): ?>
      changes as $change): ?>
    1. by
    ================================================ FILE: extensions/community/templates/lastcomments.phtml ================================================ * @author Natanael Arndt */ ?> has('infomessage')): ?>

    _($this->infomessage) ?>

    has('comments')): ?>
    comments; ?>
    has('more')): ?>

    There are more comments out there ...

    ================================================ FILE: extensions/community/templates/partials/list_community_item.phtml ================================================ author; if ($author === null) { $author = 'anonymous'; } ?>
    resource)) : ?> on resourceName ?> (date ?>): content ?>
    ================================================ FILE: extensions/community/templates/partials/list_community_main.phtml ================================================ instanceInfo as $instance){ $author = null; if (isset($this->instanceData[$instance['uri']]['creator'][0]['value'])) { $author = $this->instanceData[$instance['uri']]['creator'][0]['value']; } $options = array( 'author' => $author, 'comment' => $instance['uri'], 'commentUrl' => $instance['url'], 'content' => $this->instanceData[$instance['uri']]['content'][0]['value'], 'date' => OntoWiki_Utils::dateDifference(strtotime($this->instanceData[$instance['uri']]['date'][0]['value']), time()), 'odd' => $odd, ); if (!$this->other->singleResource) { $options['resource'] = $this->instanceData[$instance['uri']]['about'][0]['uri']; $options['resourceUrl'] = $this->instanceData[$instance['uri']]['about'][0]['url']; $options['resourceName'] = $this->instanceData[$instance['uri']]['about'][0]['value']; } echo $this->partial('partials/list_community_item.phtml', $options); $odd = !$odd; } ?>
    ================================================ FILE: extensions/community/templates/rating.phtml ================================================
    Current Rating
    Rate the Resource
    add comment icon _('Rate') ?>
    ================================================ FILE: extensions/cors/CorsPlugin.php ================================================ */ class CorsPlugin extends OntoWiki_Plugin { /* * our event method */ public function onRouteStartup() { $this->addCorsHeader(); } /* * here we add the header field(s) */ private function addCorsHeader() { $response = Zend_Controller_Front::getInstance()->getResponse(); /* * TODO: allow more CORS header fields here */ if (isset($this->_privateConfig->accessControlAllowOrigin)) { $value = $this->_privateConfig->accessControlAllowOrigin; $response->setHeader('Access-Control-Allow-Origin', $value, true); } } } ================================================ FILE: extensions/cors/default.ini ================================================ enabled = true name = "CORS" description = "Setup Cross-Origin Resource Sharing (CORS)" author = "Sebastian Tramp" authorUrl = "http://sebastian.tramp.name" url = http://enable-cors.org/ [events] 1 = onRouteStartup [private] accessControlAllowOrigin = "*" ================================================ FILE: extensions/cors/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :cors . :cors a doap:Project ; doap:name "cors" ; owconfig:privateNamespace ; owconfig:enabled "true"^^xsd:boolean ; rdfs:label "CORS" ; doap:description "Setup Cross-Origin Resource Sharing (CORS)" ; owconfig:authorLabel "Sebastian Tramp" ; doap:maintainer ; :url ; owconfig:pluginEvent event:onRouteStartup ; :accessControlAllowOrigin "*" ; doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: extensions/datagathering/DatagatheringController.php ================================================ */ class DatagatheringController extends OntoWiki_Controller_Component { // ------------------------------------------------------------------------ // --- Search related constants ------------------------------------------- // ------------------------------------------------------------------------ const SEARCH_MODE_ALL = 0; const SEARCH_MODE_PROPERTIES = 1; const SEARCH_DEFAULT_LIMIT = 20; const SEARCH_MAX_LIMIT = 100; // ------------------------------------------------------------------------ // --- Import and Sync related constants ---------------------------------- // ------------------------------------------------------------------------ /** * New versioning type codes. */ const VERSIONING_IMPORT_ACTION_TYPE = 1010; const VERSIONING_SYNC_ACTION_TYPE = 1020; /** * Syncing status codes */ const NO_SYNC_CONFIG_FOUND = 20; const NO_EDITING_RIGHTS = 10; const SYNC_SUCCESS = 30; /** * IMPORT STATUS CODES */ const IMPORT_OK = 10; const IMPORT_NO_DATA = 20; const IMPORT_NO_NEW_DATA = 21; const IMPORT_WRAPPER_ERR = 30; const IMPORT_WRAPPER_INSTANCIATION_ERR = 40; const IMPORT_NOT_EDITABLE = 50; const IMPORT_WRAPPER_NOT_AVAILABLE = 70; const IMPORT_WRAPPER_RESULT_NOT_AVAILABLE = 71; const IMPORT_CUSTOMFILTER_EXCEPTION = 80; const IMPORT_GENERAL_EXCEPTION = 90; // ------------------------------------------------------------------------ // --- Import and Sync related private properties ------------------------- // ------------------------------------------------------------------------ /** * Contains an array with matching sync configs. * * @var array */ private $_syncConfigCache = array(); // ------------------------------------------------------------------------ // --- General private properties for this component ---------------------- // ------------------------------------------------------------------------ /** * Contains the graph URI of the selected graph or the uri which is given * by the m parameter * * @var string|null */ private $_graphUri = null; /** * Contains the properties as configured in the ini file. * * @var array */ private $_properties = array(); /** * Contains the sync model helper URI as configured in the ini file. * * @var string */ private $_syncModelHelperBase = null; /** * Contains the sync model URI as configured in the ini file. * * @var string */ private $_syncModelUri = null; /** * Contains a reference to the wrapper registry. * * @var Erfurt_Wrapper_Registry */ private $_wrapperRegistry = null; // ------------------------------------------------------------------------ // --- Component initialization ------------------------------------------- // ------------------------------------------------------------------------ public function init() { parent::init(); $this->_syncModelUri = $this->_privateConfig->syncModelUri; $this->_syncModelHelperBase = $this->_privateConfig->syncModelHelperBase; // For testability we reset the wrapper registry first, since // multiple calls of this method would fail otherwise. Erfurt_Wrapper_Registry::reset(); $this->_wrapperRegisty = Erfurt_Wrapper_Registry::getInstance(); $owApp = OntoWiki::getInstance(); if (null !== $owApp->selectedModel) { $this->_graphUri = $owApp->selectedModel->getModelIri(); } else { if (isset($this->_request->m)) { $this->_graphUri = $this->_request->m; } } } // ------------------------------------------------------------------------ // --- URI and Property Search related methods ---------------------------- // ------------------------------------------------------------------------ /** * Searches for relevant URIs for given term(s). This service has two * modes. One that returns all matching URIs and one that returns only * resource URIs that are defined as properties or at least used once as * property. * * q - The mandatory parameter q contains a whitespace seperated list of * serach terms. * * mode - This optional parameter sets the search mode. The default value * is 0. In this mode all matching URIs will be returned. If the * mode is set to 1, only matching URIs are returned, that are * defined as properties or that are used as propertie at least * once. * * limit - Optional sets the maximum number of URIs the result may contain. * The default value is SEARCH_DEFAULT_LIMIT. The maximum value * is SEARCH_MAX_LIMIT. * * classes - an optional paramter which is a json_encoded array of class URIs * * This service will output a json encoded string, which represents the * result list. Each entry is returned with an title, the URI itself and * the source of that result. The entry components are sepearted by a | and * the entries are seperated by a newline. If nothing is found an empty * json encodes string will be returned. */ public function searchAction() { // Use the selected graph if present. If not, search all available graphs. if (null === $this->_graphUri) { throw new OntoWiki_Exception("model must be selected or specified with the m parameter"); } $modelUri = $this->_graphUri; // Check for the mandatory q parameter. $q = $this->_request->q; if (null === $q) { $this->_response->setRawHeader('HTTP/1.0 400 Bad Request'); echo '400 Bad Request - The q parameter is missing.'; return; } $termsArray = explode(' ', $q); // check for the classes json array $classes = array(); if (null !== $this->_request->classes) { $classes = json_decode($this->_request->classes); if (!is_array($classes)) { $classes = array(); } } // Set the search mode. if (null !== $this->_request->mode) { if ((int)$this->_request->mode === self::SEARCH_MODE_PROPERTIES) { $mode = self::SEARCH_MODE_PROPERTIES; } else { // Default to search mode all. $mode = self::SEARCH_MODE_ALL; } } else { $mode = self::SEARCH_MODE_ALL; } // Check for optional limit parameter. if (null !== $this->_request->limit) { $limit = $this->_request->limit; if ((int)$limit > 0 && $limit <= self::SEARCH_MAX_LIMIT) { $limit = (int)$limit; } else { // Default to search mode all. $limit = self::SEARCH_DEFAULT_LIMIT; } } else { $limit = self::SEARCH_DEFAULT_LIMIT; } // Check whether given term is a URI! If a URI is given we return an empty result, for some users // may want to enter URIs themself. if (count($termsArray) === 1) { foreach ($termsArray as $t) { $regExp = '/^(' . implode(':|', $this->_listIanaSchemes()) . ':).$/'; if (preg_match($regExp, $t)) { echo json_encode(''); return; } if (strlen($t) > 20) { echo json_encode(''); return; } } } $result = array(); // Step 1a: Search the local database for URIs (class restricted) $localWithRestriction = $this->_searchLocal($termsArray, $modelUri, $mode, $limit, $classes); if (count($localWithRestriction) > 0) { $result = $localWithRestriction; } // Step 1b: Search the local database for URIs (NOT class restricted) $local = $this->_searchLocal($termsArray, $modelUri, $mode, $limit); if (count($local) > 0) { // put new result values at the end of the result array foreach ($local as $resultKey => $resultValue) { if (!isset($result[$resultKey])) { $result[$resultKey] = $resultValue; } } } if ($mode === self::SEARCH_MODE_ALL && count($result) < $limit) { // Step 2: Extend the result with the results from plugins... $currentCount = count($result); require_once 'Erfurt/Event.php'; $event = new Erfurt_Event('onDatagatheringComponentSearch'); $event->translate = $this->_owApp->translate; $event->termsArray = $termsArray; $event->modelUri = $modelUri; $event->classes = $classes; $pluginResult = $event->trigger(); if (is_array($pluginResult)) { foreach ($pluginResult as $uri => $value) { if (!isset($result[$uri])) { $result[$uri] = $value; $currentCount++; } if ($currentCount === $limit) { break; } } } // 3. Step: Expand qnames if (count($result) < $limit) { $currentCount = count($result); $expanded = $this->_expandNamespaces($termsArray, $modelUri); if (count($expanded) > 0) { foreach ($expanded as $uri => $value) { if (!isset($result[$uri])) { $result[$uri] = $value; $currentCount++; } if ($currentCount === $limit) { break; } } } } // 4. If there is place for one more result, we add auto generated URI. if (count($result) < $limit) { $store = Erfurt_App::getInstance()->getStore(); $model = $store->getModel($modelUri); if ($model) { $suffix = ''; foreach ($termsArray as $t) { $suffix .= ucfirst($t); } $prefix = $model->getBaseUri(); $lastChar = substr($prefix, -1); if ($lastChar !== '/' && $lastChar !== '#') { $prefix .= '/'; } $uri = $prefix . urlencode($suffix); if (!isset($result[$uri])) { $translate = $this->_owApp->translate; $result[$uri] = implode(' ', $termsArray) . '|' . $uri . '|' . $translate->_('Generated URI'); } } } } // 5. if the user input was an URI, give this URI as result back too if (Zend_Uri::check($termsArray[0]) == true) { $translate = $this->_owApp->translate; $result = array( $termsArray[0] => $termsArray[0] . '|' . $termsArray[0] . '|' . $translate->_('your manual input') ) + $result; } $body = json_encode(implode(PHP_EOL, $result)); if (isset($this->_request->callback)) { $callback = $this->_request->callback; // build jsonp $body = $callback . ' (' . $body . ')'; } // send $response = $this->getResponse(); $response->setBody($body); } /** * Expands qnames if possible. * * @param array $termsArray * @param string $modelUri * * @return array */ private function _expandNamespaces(array $termsArray, $modelUri) { $result = array(); // We need the model here, for prefix definitions are model specific. if (null === $modelUri) { return $result; } $erfurtNamespaces = Erfurt_App::getInstance()->getNamespaces(); $namespaces = $erfurtNamespaces->getNamespacePrefixes($modelUri); $translate = $this->_owApp->translate; foreach ($termsArray as $t) { if ($pos = strpos($t, ':')) { $prefix = substr($t, 0, $pos); $local = substr($t, $pos + 1); if (isset($namespaces[$prefix])) { $uri = $namespaces[$prefix] . $local; $result[$uri] = implode(' ', $termsArray) . '|' . $uri . '|' . $translate->_('Expanded QNames'); } } } return $result; } /** * Returns a number between 0 and 1, which weights a result regardings its * value for the given search. * * @param array $termsArray * @param string $uri * @param string|null $object * * @return int */ private function _getWeight(array $termsArray, $uri, $object = null) { if (null !== $object) { $object = strtolower($object); } $weight = 0.0; if (substr($uri, -1) === '/') { $uri = substr($uri, 0, -1); } if ($i = strrpos($uri, '#')) { $uriLocalPart = substr($uri, $i + 1); } else { if ($i = strrpos($uri, '/')) { $uriLocalPart = substr($uri, $i + 1); } } if (null !== $uriLocalPart) { foreach ($termsArray as $t) { if (strpos($uriLocalPart, $t) !== false) { $weight += 0.4 / count($termsArray); } } } if (null !== $object) { foreach ($termsArray as $t) { if (strpos($object, $t) !== false) { $weight += 0.5 / count($termsArray); } } } if (strlen(implode('', $termsArray)) === strlen(str_replace(' ', '', trim($object)))) { $weight += 0.1; } return $weight; } /** * Returns a list of registered URI schemes. * * @return array */ private function _listIanaSchemes() { return array('aaa', 'aaas', 'acap', 'cap', 'cid', 'crid', 'data', 'dav', 'dict', 'dns', 'fax', 'file', 'ftp', 'go', 'gopher', 'h323', 'http', 'https', 'iax', 'icap', 'im', 'imap', 'info', 'ipp', 'iris', 'iris.beep', 'iris.xpc', 'iris.xpcs', 'iris.lwz', 'ldap', 'mailto', 'mid', 'modem', 'msrp', 'msrps', 'mtqp', 'mupdate', 'news', 'nfs', 'nntp', 'opaquelocktoken', 'pop', 'pres', 'rtsp', 'service', 'shttp', 'sieve', 'sip', 'sips', 'snmp', 'soap.beep', 'soap.beeps', 'tag', 'tel', 'telnet', 'tftp', 'thismessage', 'tip', 'tv', 'urn', 'vemmi', 'xmlrpc.beep', 'xmlrpc.beeps', 'xmpp', 'z39.50r', 'z39.50s', 'afs', 'dtn', 'mailserver', 'pack', 'tn3270', 'prospero', 'snews', 'videotex', 'wais' ); } /** * Searches the local database for URIs. If mode is set to properties only, * only defined properties and URIs that are used at least once as a * property are returned. * * the classes array is used for class restrictions * * @param array $termsArray * @param string $modelUri * @param int $mode * @param int $limit * @param array $classes * * @return array */ private function _searchLocal(array $termsArray, $modelUri, $mode, $limit, $classes = array()) { if ($mode === self::SEARCH_MODE_PROPERTIES) { return $this->_searchLocalPropertiesOnly($termsArray, $modelUri, $limit); } $store = Erfurt_App::getInstance()->getStore(); // get a store specific text-search query2 object $searchPattern = $store->getSearchPattern(implode(" ", $termsArray), $modelUri); $query = new Erfurt_Sparql_Query2(); $query->addElements($searchPattern); $projVar = new Erfurt_Sparql_Query2_Var('resourceUri'); $query->addProjectionVar($projVar); // add class restriction patterns for each class foreach ($classes as $class) { $classPattern = new Erfurt_Sparql_Query2_GroupGraphPattern(); $classPattern->addTriple( $projVar, new Erfurt_Sparql_Query2_IriRef(EF_RDF_TYPE), new Erfurt_Sparql_Query2_IriRef($class) ); $query->addElement($classPattern); } $query->setLimit(20); $query->setDistinct(true); $queryResult = $store->sparqlQuery($query, array('result_format' => 'extended')); $tempResult = array(); foreach ($queryResult['results']['bindings'] as $row) { $object = isset($row['o']) ? $row['o']['value'] : null; $weight = $this->_getWeight($termsArray, $row['resourceUri']['value'], $object); if (isset($tempResult[$row['resourceUri']['value']])) { if ($weight > $tempResult[$row['resourceUri']['value']]) { $tempResult[$row['resourceUri']['value']] = $weight; } } else { $tempResult[$row['resourceUri']['value']] = $weight; } } arsort($tempResult); require_once 'OntoWiki/Model/TitleHelper.php'; require_once 'OntoWiki/Utils.php'; if (null !== $modelUri) { $model = $store->getModel($modelUri, false); $titleHelper = new OntoWiki_Model_TitleHelper($model); } else { $titleHelper = new OntoWiki_Model_TitleHelper(); } $titleHelper->addResources(array_keys($tempResult)); $translate = $this->_owApp->translate; // create different source description strings if (count($classes) > 0) { $sourceString = $translate->_('Local Search') . ' (' . $translate->_('recommended') . ')'; } else { $sourceString = $translate->_('Local Search'); } $result = array(); foreach ($tempResult as $uri => $w) { $title = $titleHelper->getTitle($uri); if (null !== $title) { $result[$uri] = str_replace('|', 'Ι', $title) . '|' . $uri . '|' . $sourceString; } else { $result[$uri] = OntoWiki_Utils::compactUri($uri) . $uri . '|' . $sourceString; } } return $result; } /** * Searches for properties in the local database. * * @param array $termsArray * @param string $modelUri * @param int $limit * * @return array */ private function _searchLocalPropertiesOnly(array $termsArray, $modelUri, $limit) { require_once 'Erfurt/Sparql/SimpleQuery.php'; $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT DISTINCT ?uri ?o'); if (null !== $modelUri) { $query->addFrom($modelUri); } $where = '{ { ?uri ?p ?o . ?uri <' . EF_RDF_TYPE . '> ?o2 . FILTER ( sameTerm(?o2, ) || sameTerm(?o2, ) || sameTerm(?o2, ) ) FILTER (('; $uriRegexFilter = array(); foreach ($termsArray as $t) { $uriRegexFilter[] = 'regex(str(?uri), "' . $t . '", "i")'; } $where .= implode(' && ', $uriRegexFilter) . ') || (isLiteral(?o) && '; $oRegexFilter = array(); foreach ($termsArray as $t) { $oRegexFilter[] = 'regex(?o, "' . $t . '", "i")'; } $where .= implode(' && ', $oRegexFilter) . ')) } UNION {'; $where .= '?s ?uri ?o . FILTER ('; $where .= implode(' && ', $uriRegexFilter) . ') } }'; $query->setWherePart($where); $query->setOrderClause('?uri'); $query->setLimit($limit); $store = Erfurt_App::getInstance()->getStore(); $queryResult = $store->sparqlQuery($query, array('result_format' => 'extended')); $tempResult = array(); foreach ($queryResult['results']['bindings'] as $row) { if ($row['o']['type'] === 'literal') { $weight = $this->_getWeight($termsArray, $row['uri']['value'], $row['o']['value']); } else { $weight = $this->_getWeight($termsArray, $row['uri']['value']); } if (isset($tempResult[$row['uri']['value']])) { if ($weight > $tempResult[$row['uri']['value']]) { $tempResult[$row['uri']['value']] = $weight; } } else { $tempResult[$row['uri']['value']] = $weight; } } arsort($tempResult); require_once 'OntoWiki/Model/TitleHelper.php'; require_once 'OntoWiki/Utils.php'; if (null !== $modelUri) { $model = $store->getModel($modelUri, false); $titleHelper = new OntoWiki_Model_TitleHelper($model); } else { $titleHelper = new OntoWiki_Model_TitleHelper(); } $titleHelper->addResources(array_keys($tempResult)); $translate = $this->_owApp->translate; $result = array(); foreach ($tempResult as $uri => $w) { $title = $titleHelper->getTitle($uri); if (null !== $title) { $result[$uri] = str_replace('|', 'Ι', $title) . '|' . $uri . '|' . $translate->_('Local Search'); } else { $result[$uri] = OntoWiki_Utils::compactUri($uri) . $uri . '|' . $translate->_('Local Search'); } } return $result; } // ------------------------------------------------------------------------ // --- Statement import related methods ----------------------------------- // ------------------------------------------------------------------------ /** * Imports data available for a given URI and wrapper name. * * uri - Mandatory parameter that contains the URI to test. * * wrapper - Optional parameter, which contains the name of the wrapper * to use. If not given linkeddata is used as default. */ public function importAction() { // Disable rendering $this->_helper->viewRenderer->setNoRender(); $this->_helper->layout()->disableLayout(); // We require GET requests here. if (!$this->_request->isGet()) { $this->_response->setException(new OntoWiki_Http_Exception(400)); return; } // uri param is required. if (!isset($this->_request->uri)) { $this->_response->setException(new OntoWiki_Http_Exception(400)); return; } $uri = urldecode($this->_request->uri); $wrapperName = 'linkeddata'; if (isset($this->_request->wrapper)) { $wrapperName = $this->_request->wrapper; } if (null === $this->_graphUri) { throw new OntoWiki_Exception("model must be selected or specified with the m parameter"); } $presets = array(); if (isset($this->_privateConfig->fetch->preset)) { $presets = $this->_privateConfig->fetch->preset->toArray(); } $exceptedProperties = array(); if (isset($this->_privateConfig->fetch->default->exception)) { $exceptedProperties = $this->_privateConfig->fetch->default->exception->toArray(); } try { $res = self::import( $this->_graphUri, $uri, $this->_getProxyUri($uri), isset($this->_privateConfig->fetch->allData) && ((boolean)$this->_privateConfig->fetch->allData === true), $presets, $exceptedProperties, $wrapperName, $this->_privateConfig->fetch->default->mode ); } catch (Exception $e) { if (defined('_EFDEBUG')) { $errorMessage = 'An error occured: ' . $e->getMessage() . " – " . $e->getTraceAsString(); return $this->_sendResponse(false, $errorMessage, OntoWiki_Message::ERROR); } else { $res = null; } } if ($res == self::IMPORT_OK) { return $this->_sendResponse( true, 'Data was found for the given URI. Statements were added.', OntoWiki_Message::INFO ); } else { if ($res == self::IMPORT_WRAPPER_ERR) { return $this->_sendResponse( false, 'The requested wrapper failed with an error.', OntoWiki_Message::ERROR ); } else { if ($res == self::IMPORT_NO_DATA) { return $this->_sendResponse(false, 'No statements were found.', OntoWiki_Message::ERROR); } else { if ($res == self::IMPORT_NO_NEW_DATA) { return $this->_sendResponse(false, 'No new statements were found.', OntoWiki_Message::ERROR); } else { if ($res == self::IMPORT_WRAPPER_INSTANCIATION_ERR) { $this->_response->setException(new OntoWiki_Http_Exception(400)); return $this->_sendResponse( false, 'could not get wrapper instance.', OntoWiki_Message::ERROR ); } else { if ($res == self::IMPORT_NOT_EDITABLE) { $this->_response->setException(new OntoWiki_Http_Exception(403)); return $this->_sendResponse( false, 'you cannot write to this model.', OntoWiki_Message::ERROR ); } else { if ($res == self::IMPORT_WRAPPER_NOT_AVAILABLE) { return $this->_sendResponse( false, 'The requested wrapper is not available.', OntoWiki_Message::ERROR ); } else { if ($res == self::IMPORT_WRAPPER_RESULT_NOT_AVAILABLE) { return $this->_sendResponse( false, 'The requested wrapper returned no result.', OntoWiki_Message::ERROR ); } else { return $this->_sendResponse( false, 'unexpected return value.', OntoWiki_Message::ERROR ); } } } } } } } } } public static function filterStatements( $statements, $uri, $all = true, $presets = array(), $exceptedProperties = array(), $fetchMode = 'none' ) { // TODO handle configuration for import... if ($all) { // Keep all data... return $statements; } else { // Only use those parts of the data, that have the resource URI as subject. if (isset($statements[$uri])) { $statements = array( $uri => $statements[$uri] ); } else { $statements = array(); } // We also need to remove all blank node objects $newResult = array(); foreach ($statements as $s => $pArray) { foreach ($pArray as $p => $oArray) { foreach ($oArray as $oSpec) { if ($oSpec['type'] !== 'bnode') { if (!isset($newResult[$s])) { $newResult[$s] = array(); } if (!isset($newResult[$s][$p])) { $newResult[$s][$p] = array(); } $newResult[$s][$p][] = $oSpec; } } } } $statements = $newResult; } $presetMatch = false; foreach ($presets as $i => $preset) { if (self::_matchUriStatic($preset['match'], $uri)) { $presetMatch = $i; break; } } $data = $statements; $result = null; if ($presetMatch !== false) { // Use the preset if (isset($presets[$presetMatch]['mode']) && $presets[$presetMatch]['mode'] === 'none') { // Start with an empty result. $result = array(); if (isset($presets[$presetMatch]['exception'])) { foreach ($presets[$presetMatch]['exception'] as $exception) { if (isset($data[$uri][$exception])) { if (!isset($result[$uri])) { $result[$uri] = array(); } if (!isset($result[$uri][$exception])) { $result[$uri][$exception] = array(); } foreach ($data[$uri][$exception] as $o) { if ($o['type'] === 'literal') { if (isset($presets[$presetMatch]['lang'])) { foreach ($presets[$presetMatch]['lang'] as $lang) { if (isset($o['lang']) && $o['lang'] === $lang) { $result[$uri][$exception][] = $o; } } } else { $result[$uri][$exception][] = $o; } } else { $result[$uri][$exception][] = $o; } } if (isset($presets[$presetMatch]['lang'])) { if (count($result[$uri][$exception]) === 0) { foreach ($data[$uri][$exception] as $o) { if (!isset($o['lang'])) { $result[$uri][$exception][] = $o; break; } } } } } } } } else { // Use the default rule. // Start with all data. $result = $data; if (isset($presets[$presetMatch]['exception'])) { foreach ($presets[$presetMatch]['exception'] as $exception) { if (isset($data[$uri][$exception])) { if (isset($result[$uri][$exception])) { unset($result[$uri][$exception]); } } } } } } else { if ($fetchMode === 'none') { // Start with an empty result. $result = array(); foreach ($exceptedProperties as $exception) { if (isset($data[$uri][$exception])) { if (!isset($result[$uri])) { $result[$uri] = array(); } $result[$uri][$exception] = $data[$uri][$exception]; } } } else { // Start with all data. $result = $data; foreach ($exceptedProperties as $exception) { if (isset($data[$uri][$exception])) { if (isset($result[$uri][$exception])) { unset($result[$uri][$exception]); } } } } } $statements = $result; return $statements; } /** * * @param string $graphUri * @param string $uri * @param type $locator * @param boolean $all * @param array $presets * @param array $exceptedProperties * @param string $wrapperName * @param string $fetchMode * @param string $action * @param boolean $versioning * * @return int status code */ //TODO refactor these 11 parameters (use a config object or break it down with adapters etc) public static function import( $graphUri, $uri, $locator, $all = true, $presets = array(), $exceptedProperties = array(), $wrapperName = 'linkeddata', $fetchMode = 'none', $action = 'add', $versioning = true, $filterCallback = null ) { // Check whether user is allowed to write the model. $erfurt = Erfurt_App::getInstance(); $store = $erfurt->getStore(); $storeGraph = $store->getModel($graphUri); if (!$storeGraph || !$storeGraph->isEditable()) { return self::IMPORT_NOT_EDITABLE; } $r = new Erfurt_Rdf_Resource($uri); $r->setLocator($locator); // Try to instanciate the requested wrapper $wrapper = null; try { $wrapper = Erfurt_Wrapper_Registry::getInstance()->getWrapperInstance($wrapperName); } catch (Erfurt_Wrapper_Exception $e) { return self::IMPORT_WRAPPER_INSTANCIATION_ERR; } if (null == $wrapper) { return self::IMPORT_WRAPPER_NOT_AVAILABLE; } $wrapperResult = null; try { $wrapperResult = $wrapper->run($r, $graphUri, $all); } catch (Erfurt_Wrapper_Exception $e) { return self::IMPORT_WRAPPER_ERR; } if ($wrapperResult === false) { return self::IMPORT_WRAPPER_RESULT_NOT_AVAILABLE; } else { if (is_array($wrapperResult)) { if (isset($wrapperResult['status_codes'])) { if (in_array(Erfurt_Wrapper::RESULT_HAS_ADD, $wrapperResult['status_codes'])) { $newStatements = $wrapperResult['add']; //default filter $newStatements = self::filterStatements( $newStatements, $uri, $all, $presets, $exceptedProperties, $fetchMode ); //custom filter if ($filterCallback != null && is_array($filterCallback)) { try { $newStatements = call_user_func($filterCallback, $newStatements); } catch (Exception $e) { return self::IMPORT_CUSTOMFILTER_EXCEPTION; } } $stmtBeforeCount = $store->countWhereMatches( $graphUri, '{ ?s ?p ?o }', '*' ); if ($versioning) { // Prepare versioning... $versioning = $erfurt->getVersioning(); $actionSpec = array( 'type' => self::VERSIONING_IMPORT_ACTION_TYPE, 'modeluri' => $graphUri, 'resourceuri' => $uri ); // Start action $versioning->startAction($actionSpec); } if ($action == 'add') { try { $store->addMultipleStatements($graphUri, $newStatements); } catch (Exception $e) { $versioning->abortAction(); if (defined('_EFDEBUG')) { throw $e; } return self::IMPORT_GENERAL_EXCEPTION; } } else { if ($action == 'update') { $queryoptions = array( 'use_ac' => false, 'result_format' => Erfurt_Store::RESULTFORMAT_EXTENDED, 'use_additional_imports' => false ); $oldStatements = $store->sparqlQuery( 'SELECT * FROM <' . $graphUri . '> WHERE { ?s ?p ?o }', $queryoptions ); //transform resultset to rdf/php statements $modelOld = new Erfurt_Rdf_MemoryModel(); $modelOld->addStatementsFromSPOQuery($oldStatements); $modelNew = new Erfurt_Rdf_MemoryModel($newStatements); $storeGraph->updateWithMutualDifference( $modelOld->getStatements(), $modelNew->getStatements() ); } } if ($versioning) { $versioning->endAction(); } $stmtAfterCount = $store->countWhereMatches( $graphUri, '{ ?s ?p ?o }', '*' ); $stmtAddCount = $stmtAfterCount - $stmtBeforeCount; if ($stmtAddCount > 0) { // TODO test ns // If we added some statements, we check for additional namespaces and add them. if (in_array(Erfurt_Wrapper::RESULT_HAS_NS, $wrapperResult['status_codes'])) { $namespaces = $wrapperResult['ns']; $erfurtNamespaces = $erfurt->getNamespaces(); foreach ($namespaces as $ns => $prefix) { try { $erfurtNamespaces->addNamespacePrefix( $graphUri, $prefix, $ns, false ); } catch (Exception $e) { // Ignore... } } } return self::IMPORT_OK; } else { if (count($newStatements) > 0) { return self::IMPORT_NO_NEW_DATA; } else { return self::IMPORT_NO_DATA; } } } else { return self::IMPORT_NO_DATA; } } else { return self::IMPORT_WRAPPER_ERR; } } else { return self::IMPORT_WRAPPER_ERR; } } } private function _sendResponse($returnValue, $message = null, $messageType = OntoWiki_Message::SUCCESS) { if (null !== $message) { $translate = $this->_owApp->translate; $message = $translate->_($message); $this->_owApp->appendMessage( new OntoWiki_Message($message, $messageType) ); } $returnValue = array( 'code' => $returnValue, 'message' => $message ); $this->_response->setHeader('Content-Type', 'application/json', true); $this->_response->setBody(json_encode($returnValue)); } // ------------------------------------------------------------------------ // --- Statement sync related methods ------------------------------------- // ------------------------------------------------------------------------ /** * Filters a result regarding the configured sparql query. * * @param array $result * @param string $uri * @param string $wrapperName * @param string $modelUri * * @return array */ private function _filterResult($result, $uri, $wrapperName, $modelUri) { $store = Erfurt_App::getInstance()->getStore(); $syncConfig = $this->_getSyncConfig($uri, $wrapperName, $modelUri); if (!is_array($syncConfig) || count($syncConfig) === 0) { return array(); } $syncConfig = $syncConfig[0]; // TODO We need support for in-memory models... this is a workaround $tempModelUri = $this->_syncModelHelperBase . md5($uri . $wrapperName . $modelUri . time()); $tempModel = $store->getNewModel($tempModelUri, '', 'rdf', false); $store->addMultipleStatements($tempModelUri, $result); $simpleQuery = Erfurt_Sparql_SimpleQuery::initWithString($syncConfig['syncQuery']); $simpleQuery->addFrom($tempModelUri); $sparqlResult = $store->sparqlQuery($simpleQuery, array('result_format' => 'extended', 'use_ac' => false)); $store->deleteModel($tempModelUri); $retVal = array(); foreach ($sparqlResult['results']['bindings'] as $row) { if (!isset($retVal[$row['s']['value']])) { $retVal[$row['s']['value']] = array(); } if (!isset($retVal[$row['s']['value']][$row['p']['value']])) { $retVal[$row['s']['value']][$row['p']['value']] = array(); } $oArray = array( 'value' => $row['o']['value'] ); if ($row['o']['type'] === 'typed-literal') { $oArray['type'] = 'literal'; $oArray['dataytpe'] = $row['o']['datatype']; } else { $oArray['type'] = $row['o']['type']; } if (isset($row['o']['xml:lang'])) { $oArray['lang'] = $row['o']['xml:lang']; } $retVal[$row['s']['value']][$row['p']['value']][] = $oArray; } return $retVal; } /** * Fetches the data from the wrapper. * * @param string $uri * @param string $wrapperName * @param string $modelUri * * @return array */ private function _getData($uri, $wrapperName, $modelUri) { try { $wrapper = $this->_wrapperRegistry->getWrapperInstance($wrapperName); $wrapperResult = $wrapper->run($uri, $modelUri); if (is_array($wrapperResult) && isset($wrapperResult['add'])) { $wrapperResult = $wrapperResult; } else { $wrapperResult = array(); } } catch (Exception $e) { $wrapperResult = array(); } return $wrapperResult; } private function _getProxyUri($uri) { // If at least one rewrite rule is defined, we iterate through them. if (isset($this->_privateConfig->rewrite)) { $rulesArray = $this->_privateConfig->rewrite->toArray(); foreach ($rulesArray as $ruleId => $ruleSpec) { $proxyUri = preg_replace($ruleSpec['pattern'], $ruleSpec['replacement'], $uri); if ($proxyUri !== $uri) { return $proxyUri; } } } return null; } private function _matchUri($pattern, $uri) { if ((substr($pattern, 0, 7) !== 'http://')) { $pattern = 'http://' . $pattern; } if ((substr($uri, 0, strlen($pattern)) === $pattern)) { return true; } else { return false; } } private static function _matchUriStatic($pattern, $uri) { if ((substr($pattern, 0, 7) !== 'http://')) { $pattern = 'http://' . $pattern; } if ((substr($uri, 0, strlen($pattern)) === $pattern)) { return true; } else { return false; } } } ================================================ FILE: extensions/datagathering/DatagatheringHelper.php ================================================ */ class DatagatheringHelper extends OntoWiki_Component_Helper { public function init() { $pathBase = $this->_owApp->extensionManager->getComponentUrl('datagathering'); $this->_owApp->view->headScript()->appendFile($pathBase . 'scripts/jquery.autocomplete.js'); $this->_owApp->view->headScript()->appendFile($pathBase . 'datagathering.js'); $this->_owApp->view->headLink()->appendStylesheet($pathBase . 'css/jquery.autocomplete.css'); } } ================================================ FILE: extensions/datagathering/DatagatheringPlugin.php ================================================ */ class DatagatheringPlugin extends OntoWiki_Plugin { // ------------------------------------------------------------------------ // --- Private properties ------------------------------------------------- // ------------------------------------------------------------------------ /** * Contains propertiy URIs configured in the ini file * * @var array */ private $_properties = array(); /** * The URI of the sync model as configured in the ini. * * @var string */ private $_syncModelUri = null; /** * Contains the fetched sync configuration in order to avoid multiple * fetching of it via SPARQL queries. * * @var array */ private $_syncConfigCache = null; /** * Contains the fetched sync configurations in order to avoid multiple * fetching of them via SPARQL queries. * * @var array */ private $_syncConfigListCache = null; /** * The initialization method. Sets some properties. */ public function init() { parent::init(); if ($this->_privateConfig->sync->enabled && isset($this->_privateConfig->properties)) { $this->_properties = $this->_privateConfig->properties->toArray(); } $this->_syncModelUri = $this->_privateConfig->syncModelUri; // Translation hack in order to enable the plugin to translate... $translate = OntoWiki::getInstance()->translate; $translate->addTranslation( $this->_pluginRoot . 'languages', null, array('scan' => Zend_Translate::LOCALE_FILENAME) ); $translate->setLocale(OntoWiki::getInstance()->config->languages->locale); } // ------------------------------------------------------------------------ // --- Plugin handler methods --------------------------------------------- // ------------------------------------------------------------------------ /** * Event handler method, which is called on menu creation. Adds some * datagathering relevant menu entries. * * @param Erfurt_Event $event * * @return bool */ public function onCreateMenu($event) { $menu = $event->menu; $resource = $event->resource; $model = $event->model; $owApp = OntoWiki::getInstance(); // We only add entries to the menu, if all params are given and the // model is editable. if ((null === $resource) || (null === $model) || !$model->isEditable() || !$owApp->erfurt->getAc()->isModelAllowed('edit', $owApp->selectedModel) ) { return; } $owApp = OntoWiki::getInstance(); $translate = $owApp->translate; $wrapperRegistry = Erfurt_Wrapper_Registry::getInstance(); $activeWrapperList = $wrapperRegistry->listActiveWrapper(); if ((boolean)$this->_privateConfig->sync->enabled) { $syncConfigList = $this->_listSyncConfigs(); } else { $syncConfigList = array(); } $uri = (string)$resource; $modelUri = (string)$model; $menuArray = array(); // Check all active wrapper extensions, whether URI is handled. Also // check, whether a sync config exists. foreach ($activeWrapperList as $wrapperName) { $hash = $this->_getHash($uri, $wrapperName, $modelUri); $r = new Erfurt_Rdf_Resource($uri); $r->setLocator($this->_getProxyUri($uri)); $wrapperInstance = $wrapperRegistry->getWrapperInstance($wrapperName); if ($wrapperInstance->isHandled($r, $modelUri)) { $menuArray[$wrapperName] = array( 'instance' => $wrapperInstance ); if (isset($syncConfigList[$hash])) { $menuArray[$wrapperName]['sync'] = true; } } } // Only add a separator, if at least one active wrapper exists. if (count($menuArray) > 0) { $menu->appendEntry(OntoWiki_Menu::SEPARATOR); } foreach ($menuArray as $wrapperName => $wrapperArray) { $wrapperInstance = $wrapperArray['instance']; if (isset($wrapperArray['sync']) && $wrapperArray['sync'] === true) { $message = $translate->_('Sync Data with %1$s'); $menu->appendEntry( sprintf($message, $wrapperInstance->getName()), array( 'about' => $uri, 'class' => 'sync_data_button wrapper_' . $wrapperName ) ); } else { $message = $translate->_('Import Data with %1$s'); $menu->appendEntry( sprintf($message, $wrapperInstance->getName()), array( 'about' => $uri, 'class' => 'fetch_data_button wrapper_' . $wrapperName ) ); } // Configure for sync entry. if ((boolean)$this->_privateConfig->sync->enabled) { $configUrl = $owApp->config->urlBase . 'datagathering/config?uri=' . urlencode($uri) . '&wrapper=' . urlencode($wrapperName); if ($event->isModel) { $configUrl .= '&m=' . urlencode($uri); } $message = $translate->_('Configure Sync with %1$s'); $menu->appendEntry( sprintf($message, $wrapperInstance->getName()), $configUrl ); } } return true; } /** * Event handler method, which is called whenever the property view of * a resource will be displayed. Adds the location bar to the menu and * adds a message if a resource is configured for sync. * * @param Erfurt_Event $event * * @return bool */ public function onPropertiesAction($event) { $translate = OntoWiki::getInstance()->translate; $session = new Zend_Session_Namespace(_OWSESSION); // Add the location bar menu entry. $menu = OntoWiki_Menu_Registry::getInstance()->getMenu('resource'); $menu->prependEntry(OntoWiki_Menu::SEPARATOR); if ($session->showLocationBar === false) { $entry = $translate->_('Show/Hide Location Bar'); $menu->prependEntry($entry, array('class' => 'location_bar show')); } else { $entry = $translate->_('Show/Hide Location Bar'); $menu->prependEntry($entry, array('class' => 'location_bar')); } $uri = $event->uri; $modelUri = $event->graph; if ((boolean)$this->_privateConfig->sync->enabled) { $syncConfig = $this->_getSyncConfig($uri, 'linkeddata', $modelUri); } else { $syncConfig = false; } if ($syncConfig === false || $syncConfig['checkHasChanged'] === false) { return false; } // Thre resource is configured for sync, so show a message box. $message = ' ' . $translate->_('This Resource is configured for Sync') . '.' . '' . '
    '; $message .= ''; if (isset($syncConfig['lastSyncDateTime'])) { $message .= $translate->_('Last Sync') . ': ' . date('r', strtotime($syncConfig['lastSyncDateTime'])); $message .= '
    '; } $message .= ''; $message .= '
    '; $message .= ''; $message .= '
    '; OntoWiki::getInstance()->appendMessage( new OntoWiki_Message($message, OntoWiki_Message::INFO, array('escape' => false)) ); return true; } /** * Event handler method, which is called before tabs content is created. * Adds the location bar to the page. * * @param Erfurt_Event $event * * @return string */ public function onPreTabsContentAction($event) { $translate = OntoWiki::getInstance()->translate; $uri = $event->uri; $html = ''; return $html; } /** * Event handler method, which is called when a resource is deleted. * We remove all sync configurations with that resource. * * @param Erfurt_Event $event * * @return bool */ public function onDeleteResources($event) { if ($this->_privateConfig->sync->enabled) { $modelUri = $event->modelUri; $uriArray = $event->resourceArray; require_once 'Erfurt/Sparql/SimpleQuery.php'; $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT ?s ?o'); $query->addFrom($this->_syncModelUri); $query->setWherePart( 'WHERE { ?s <' . EF_RDF_TYPE . '> <' . $this->_properties['syncConfigClass'] . '> . ?s <' . $this->_properties['targetModel'] . '> <' . $modelUri . '> . ?s <' . $this->_properties['syncResource'] . '> ?o . }' ); $store = Erfurt_App::getInstance()->getStore(); $result = $store->sparqlQuery($query, array('use_ac' => false)); foreach ($result as $row) { if (in_array($row['o'], $uriArray)) { $store->deleteMatchingStatements( $this->_syncModelUri, $row['s'], null, null, array('use_ac' => false) ); } } } return true; } /** * Event handler method, which is called before a model is deleted. * We remove all sync configurations with that model. * * @param Erfurt_Event $event * * @return bool */ public function onPreDeleteModel($event) { if ($this->_privateConfig->sync->enabled) { $modelUri = $event->modelUri; require_once 'Erfurt/Sparql/SimpleQuery.php'; $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT ?s'); $query->addFrom($this->_syncModelUri); $query->setWherePart( 'WHERE { ?s <' . EF_RDF_TYPE . '> <' . $this->_properties['syncConfigClass'] . '> . ?s <' . $this->_properties['targetModel'] . '> <' . $modelUri . '> . }' ); $store = Erfurt_App::getInstance()->getStore(); $result = $store->sparqlQuery($query, array('use_ac' => false)); foreach ($result as $row) { $store->deleteMatchingStatements($this->_syncModelUri, $row['s'], null, null, array('use_ac' => false)); } } return true; } // ------------------------------------------------------------------------ // --- Private helpder methods -------------------------------------------- // ------------------------------------------------------------------------ /** * Returns a md5 hash of the given parameters. * * @param string $uri * @param string $wrapperName * @param string $modelUri * * @return string */ private function _getHash($uri, $wrapperName, $modelUri) { $uri = (string)$uri; $wrapperName = (string)$wrapperName; $modelUri = (string)$modelUri; return md5(($uri . $wrapperName . $modelUri)); } /** * Returns the sync config for the given parameters or false, if no such exists. * * @param string $uri The resource uri. * @param string $wrapperName The wrapper name. * @param string $modelUri The model uri. * * @return array|bool */ private function _getSyncConfig($uri, $wrapperName, $modelUri) { if (null === $this->_syncConfigCache) { $store = Erfurt_App::getInstance()->getStore(); require_once 'Erfurt/Sparql/SimpleQuery.php'; $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT ?s ?p ?o'); $query->addFrom($this->_syncModelUri); $where = 'WHERE { ?s ?p ?o . ?s <' . EF_RDF_TYPE . '> <' . $this->_properties['syncConfigClass'] . '> . ?s <' . $this->_properties['syncResource'] . '> <' . $uri . '> . ?s <' . $this->_properties['targetModel'] . '> <' . $modelUri . '> . ?s <' . $this->_properties['wrapperName'] . '> "' . $wrapperName . '" . }'; $query->setWherePart($where); $result = $store->sparqlQuery($query, array('use_ac' => false)); if (count($result) === 0) { return false; } $retVal = array(); foreach ($result as $row) { if (!isset($retVal[$row['s']])) { $retVal[$row['s']] = array( 'uri' => $row['s'] ); } switch ($row['p']) { case $this->_properties['targetModel']: $retVal[$row['s']]['targetModel'] = $row['o']; break; case $this->_properties['syncResource']: $retVal[$row['s']]['syncResource'] = $row['o']; break; case $this->_properties['wrapperName']: $retVal[$row['s']]['wrapperName'] = $row['o']; break; case $this->_properties['lastSyncPayload']: $retVal[$row['s']]['lastSyncPayload'] = unserialize($row['o']); break; case $this->_properties['lastSyncDateTime']: $retVal[$row['s']]['lastSyncDateTime'] = $row['o']; break; case $this->_properties['syncQuery']: $retVal[$row['s']]['syncQuery'] = $row['o']; break; case $this->_properties['checkHasChanged']: $retVal[$row['s']]['checkHasChanged'] = (bool)$row['o']; break; } } $this->_syncConfigCache = array_values($retVal); $this->_syncConfigCache = $this->_syncConfigCache[0]; // Only return one config! } return $this->_syncConfigCache; } /** * Returns all existing sync configurations. * * @return array|bool */ private function _listSyncConfigs() { if (null === $this->_syncConfigListCache) { $store = Erfurt_App::getInstance()->getStore(); require_once 'Erfurt/Sparql/SimpleQuery.php'; $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT ?s ?p ?o'); $query->addFrom($this->_syncModelUri); $where = 'WHERE { ?s ?p ?o . ?s <' . EF_RDF_TYPE . '> <' . $this->_properties['syncConfigClass'] . '> . }'; $query->setWherePart($where); $result = $store->sparqlQuery($query, array('use_ac' => false)); if (count($result) === 0) { return false; } $retVal = array(); foreach ($result as $row) { if (!isset($retVal[$row['s']])) { $retVal[$row['s']] = array( 'uri' => $row['s'] ); } switch ($row['p']) { case $this->_properties['targetModel']: $retVal[$row['s']]['targetModel'] = $row['o']; break; case $this->_properties['syncResource']: $retVal[$row['s']]['syncResource'] = $row['o']; break; case $this->_properties['wrapperName']: $retVal[$row['s']]['wrapperName'] = $row['o']; break; case $this->_properties['lastSyncPayload']: $retVal[$row['s']]['lastSyncPayload'] = unserialize($row['o']); break; case $this->_properties['lastSyncDateTime']: $retVal[$row['s']]['lastSyncDateTime'] = $row['o']; break; case $this->_properties['syncQuery']: $retVal[$row['s']]['syncQuery'] = $row['o']; break; case $this->_properties['checkHasChanged']: $retVal[$row['s']]['checkHasChanged'] = (bool)$row['o']; break; } } $cacheVal = array(); foreach ($retVal as $s => $valueArray) { $hash = $this->_getHash( $valueArray['syncResource'], $valueArray['wrapperName'], $valueArray['targetModel'] ); $cacheVal[$hash] = $valueArray; } $this->_syncConfigListCache = $cacheVal; } return $this->_syncConfigListCache; } private function _getProxyUri($uri) { // If at least one rewrite rule is defined, we iterate through them. if (isset($this->_privateConfig->rewrite)) { $rulesArray = $this->_privateConfig->rewrite->toArray(); foreach ($rulesArray as $ruleId => $ruleSpec) { $proxyUri = @preg_replace($ruleSpec['pattern'], $ruleSpec['replacement'], $uri); if ($proxyUri !== $uri) { return $proxyUri; } } } return null; } } ================================================ FILE: extensions/datagathering/SyncSchema.rdf ================================================ ]> This schema model provides the vocabulary for syncing resources with OntoWiki. This class contains all sync configurations. This property defines the model, which will contain the statements. This property defines the source of the data.. ================================================ FILE: extensions/datagathering/css/jquery.autocomplete.css ================================================ .ac_results { padding: 0px; border: 1px solid black; background-color: white; overflow: hidden; z-index: 99999; } .ac_results ul { width: 100%; list-style-position: outside; list-style: none; padding: 0; margin: 0; } .ac_results li { margin: 0px; padding: 2px 5px; cursor: default; display: block; /* if width will be 100% horizontal scrollbar will apear when scroll mode will be used */ /*width: 100%;*/ font: menu; font-size: 12px; /* it is very important, if line-height not setted or setted in relative units scroll will be broken in firefox */ line-height: 16px; overflow: hidden; } .ac_loading { background: white url('indicator.gif') right center no-repeat; } .ac_odd { background-color: #eee; } .ac_over { background-color: #0A246A; } ================================================ FILE: extensions/datagathering/datagathering.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() { // ------------------------------------------------------------------------ // --- Location Bar ------------------------------------------------------- // ------------------------------------------------------------------------ // Bind the menu entry to the show and hide methods on click. $('a.location_bar').parent('li').click(function() { if ($('a.location_bar').hasClass('show')) { showLocationBar(); sessionStore('showLocationBar', true, {method: 'set'}); } else { hideLocationBar(); sessionStore('showLocationBar', false, {method: 'unset'}); } }); // Show location bar if it is active... if (typeof($('a.location_bar').get(0)) != 'undefined' && !$('a.location_bar').hasClass('show')) { showLocationBar(); } // Click event for the View button $('#location_open').live('click', function(e) { if (e.which == 1) { window.location = urlBase + 'resource/properties?r=' + encodeURIComponent($('#location_bar_input').val()); } }); // Enter event for the View button $('#location_bar_input').live('keypress', function(evt) { if (evt.which == 13) { window.location = urlBase + 'resource/properties?r=' + encodeURIComponent($('#location_bar_input').val()); } }); // ------------------------------------------------------------------------ // --- Datagathering ------------------------------------------------------ // ------------------------------------------------------------------------ // Datagathering via resource context menus $('.fetch_data_button').livequery('click', function() { var uriValue = $(this).attr('about'); var classesArray = $(this).attr('class').split(' '); var wrapperName = ''; for (var i=0; i
    '); var request = $.ajax({ url: url, data: { uri: uriValue, wrapper: wrapperName }, success: function(data, textStatus, jqXHR) { $('.contextmenu-enhanced .contextmenu').fadeOut(effectTime, function(){ $(this).remove(); }); window.location = document.URL; }, error: function(jqXHR, textStatus, errorThrown) { $('.contextmenu-enhanced .contextmenu').fadeOut(effectTime, function(){ $(this).remove(); }); window.location = document.URL; }, timeout: 30000 }); return false; }); // Datagathering via resource context menus $('.sync_data_button').livequery('click', function() { var uriValue = $(this).attr('about'); var classesArray = $(this).attr('class').split(' '); var wrapperName = ''; for (var i=0; i
    '); $.getJSON(url, {uri: uriValue, wrapper: wrapperName}, function(data) { if (data['redirect']) { $('.contextmenu-enhanced .contextmenu').fadeOut(effectTime, function(){ $(this).remove(); }) window.location = data['redirect']; return false; } $('.contextmenu-enhanced .contextmenu').fadeOut(effectTime, function(){ $(this).remove(); }) window.location = document.URL; return false; }); return false; }); // Check for updates. Currently only linkeddata is supported! var checkElem = $('#dg_check_update'); if (typeof(checkElem.get(0)) != 'undefined') { var uriValue = $('div.section-mainwindows table').eq(0).attr('about'); var url = urlBase + 'datagathering/modified'; $.getJSON(url, {uri: uriValue, wrapper: 'linkeddata'}, function(data) { if (data != false) { $('#dg_configured_text').hide(); $('#dg_updated_text').show(); $('#dg_lastmod_date').html(data.lastMod); $('#dg_lastmod_date').show(); $('#dg_lastmod_text').show(); $('#dg_sync_button').show(); checkElem.parent('p').removeClass('info').addClass('success'); $('#dg_sync_button').livequery('click', function() { var url = urlBase + 'datagathering/sync'; $(this).append('
    '); $.getJSON(url, {uri: uriValue, wrapper: 'linkeddata'}, function(data) { window.location = document.URL; }); return false; }); } }); } }); // ------------------------------------------------------------------------ // --- Location Bar related functions ------------------------------------- // ------------------------------------------------------------------------ /** * Shows the location bar. *//** * Function that executes a URI search. */ function locationBarUriSearch(term, cb) { var searchUrl = urlBase + 'datagathering/search?q=' + term; $.getJSON(searchUrl, function(jsonData) { cb(jsonData); }); } function showLocationBar() { $('a.location_bar').removeClass('show'); $('#location_bar_container').show(); // $('#location_bar_input')._autocomplete(function(term, cb) { locationBarUriSearch(term, cb); }, { // minChars: 3, // delay: 1000, // max: 100, // formatItem: function(data, i, n, term) { // return '
    \ // ' + data[2] + '\ //
    \ // ' + data[0] + '\ //
    \ // ' + data[1] + '\ //
    '; // } // }); $('#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): ?>



      checkHasChanged ?> />

      ================================================ 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 Scheme a 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 authentificaiton time of last metadata change of the Extension mark 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. qiufeng Feng Qiu account_1 qiufeng Aric Qiu account_1 informatik Christian Maier account_3 This is a very very very very very svery very very very very very very very very short desciption for test_plugin_1 2009-03-15T13:00:00.000 test_plugin_1 This is a very svery very very very very svery very very very very very very short description for test_plugin_2 2009-03-15T12:51:36.000 test_plugin_2 This is a very very svery very very very very svery very very very very very very short description for test_plugin_3 2009-03-15T12:51:36.000 test_plugin_3 A plugin that renders values of certain properties as audio. 2009-05-02T13:00:00.000 audiolink A plugin that renders values of certain properties as video. 2009-05-02T13:00:00.000 videolink http://stinfwww.informatik.uni-leipzig.de/~bss03kpx/testplugin1.zip 1.0 Test Plugin Ontowiki Extension http://stinfwww.informatik.uni-leipzig.de/~bss03kpx/testplugin2.zip 1.0 Test Plugin Ontowiki Extension http://stinfwww.informatik.uni-leipzig.de/~bss03kpx/testplugin3.zip 1.0 Test Plugin Ontowiki Extension http://stinfwww.informatik.uni-leipzig.de/~bss03kpx/audiolink.zip 1.0 Audio Plugin Ontowiki Extension Link Christian Maier http://stinfwww.informatik.uni-leipzig.de/~bss03kpx/videolink.zip 1.0 Video Plugin Ontowiki Extension Link Christian Maier ================================================ FILE: extensions/exconf/resources/PluginRepository.rdf ================================================ ]> OWL for the Miniworld of the Extension Repository Scheme a 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 authentificaiton time of last metadata change of the Extension mark 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('
      1. ' +title+ '
      2. '); } else { target.append('
      3. ' +title+ '
      4. '); } even = !even; }); }; ================================================ FILE: extensions/exconf/resources/togglebutton.css ================================================ /** * Style for the jquery.togglebutton plugin. * @copyright Copyright (c) 2014, {@link http://aksw.org AKSW} * @license http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL) * @author jonas * @since 21.08.205, 21:39:53 */ .togglebutton { border: none; background: transparent; width: 3em; height: 1.5em; -moz-border-radius: 0.75em !important; -webkit-border-radius: 0.75em !important; border-radius: 0.75em !important; display:inline-block; vertical-align:text-bottom; opacity:0.5; } .togglebutton:hover {opacity:1;} li.compact .togglebutton {width:1em; height:1em; vertical-align:middle; cursor: pointer; } .togglebutton .slider { border: none; background-color: #999; width: 1.5em; height: 1.5em; -moz-border-radius: 0.75em !important; -webkit-border-radius: 0.75em !important; border-radius: 0.75em !important; -moz-box-shadow:inset 0 0 0.75em #000; -webkit-box-shadow:inset 0 0 0.75em #000; box-shadow:inset 0 0 0.75em #000; cursor: pointer; } ================================================ FILE: extensions/exconf/templates/exconf/archiveuploadform.phtml ================================================
        ================================================ FILE: extensions/exconf/templates/exconf/conf.phtml ================================================  [empty] + $value){ ?>
         -
        >
         
        + 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(" - "); }); $(".addPropertyEmpty").submit(function(){return false;}); $(".addPropertyEmpty").live("click",function(){ $(this).parent().html("
         - 
        +"); }); $(".removeProperty").submit(function(){return false;}); $(".removeProperty").live("click",function(){ if($(this).parent().parent().parent().children().size() == 1){ $(this).parent().parent().parent().parent().next().remove(); $(this).parent().parent().parent().parent().replaceWith(" "); } else { $(this).parent().parent().remove(); } }); $(".splitProperty").submit(function(){return false;}); $(".splitProperty").live("click",function(){ $(this).prev().replaceWith("
         - 
        +"); $(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.

        name, $this->coreExtensions)){ ?>
        enabled
        enabled){ echo "selected=\"true\""; } ?>>
        private config); ?>
        ================================================ FILE: extensions/exconf/templates/exconf/explorerepo.phtml ================================================ repoUrl; ?>" />*/?> ================================================ FILE: extensions/exconf/templates/exconf/installarchiveremote.phtml ================================================ ================================================ FILE: extensions/exconf/templates/exconf/installarchiveupload.phtml ================================================ ================================================ FILE: extensions/exconf/templates/exconf/list.phtml ================================================ isAllowed){ $ow = OntoWiki::getInstance(); $this->headLink()->appendStylesheet($ow->extensionManager->getComponentUrl('exconf')."resources/exconf.css"); $this->headScript()->appendFile($ow->extensionManager->getComponentUrl('exconf')."resources/exconf.js"); $this->headScript()->appendFile($ow->extensionManager->getComponentUrl('exconf')."resources/jquery.togglebutton.js"); $this->headLink()->appendStylesheet($ow->extensionManager->getComponentUrl('exconf')."resources/togglebutton.css"); ?>
        Show extensions

        Extensions

          extensions as $name => $extension){ if(in_array($name, $this->coreExtensions)){ $isCoreExtension = true; } else { $isCoreExtension = false; } ?>
        1. "> Close
          urlBase.(!isset($extension->confAction) ? 'exconf/conf/?name='. $name : $extension->confAction); ?>

          title; ?> author)) { echo 'by '.(isset($extension->authorUrl)?''.$extension->author.'':$extension->author).''; } ?>

          enabled) && $extension->enabled){ echo "selected=\"true\""; } ?>>

          description) ? $extension->description : "Extension does not provide a description."; ?>

        ================================================ FILE: extensions/exconf/templates/partials/list_extensions_main.phtml ================================================ instances->hasData()): ?>
          instanceInfo as $instance){ $instanceUri = $instance['uri']; if(isset($this->instanceData[$instanceUri]['name'])){ $name = $this->instanceData[$instanceUri]['name'][0]['origvalue']; } else { $name = $instanceUri; } if(isset($this->instanceData[$instanceUri]['revision'])){ $revision = $this->instanceData[$instanceUri]['revision'][0]['value']; } else { continue; } $owVersion = '0.9.6'; $minVersion = !isset($this->instanceData[$instanceUri]['minOwVersion']) ? null : $this->instanceData[$instanceUri]['minOwVersion'][0]['value']; $installable = ($minVersion == null || version_compare($minVersion, $owVersion, '<=')); if(!$installable){ continue; //skip } if(!isset($highestVersions[$name]) || version_compare($highestVersions[$name], $revision, '<')){ $highestVersions[$name] = $revision; } } foreach ($this->instanceInfo as $instance){ ?>
        1. instanceData[$instanceUri]['name'])){ $name = $this->instanceData[$instanceUri]['name'][0]['origvalue']; } else { $name = $instanceUri; //TODO title helper } if(isset($this->instanceData[$instanceUri]['title'])){ $title = $this->instanceData[$instanceUri]['title'][0]['value']; } else { $title = $name; } if(isset($this->instanceData[$instanceUri]['description'])){ $description = $this->instanceData[$instanceUri]['description'][0]['value']; } else { $description = 'no description'; } if(isset($this->instanceData[$instanceUri]['page'])){ $page = $this->instanceData[$instanceUri]['page'][0]['origvalue']; } else { $page = null; } if(isset($this->instanceData[$instanceUri]['author'])){ $author = $this->instanceData[$instanceUri]['author'][0]['url']; } else { $author = null; } if(isset($this->instanceData[$instanceUri]['authorLabel'])){ $authorLabel = $this->instanceData[$instanceUri]['authorLabel'][0]['value']; } else { if(isset($this->instanceData[$instanceUri]['author'][0])){ $authorLabel = $this->instanceData[$instanceUri]['author'][0]['value']; } else { $authorLabel = 'unknown author'; } } if(isset($this->instanceData[$instanceUri]['homepage'])){ $authorPage = $this->instanceData[$instanceUri]['homepage'][0]['origvalue']; } else { $authorPage = null; } if(isset($this->instanceData[$instanceUri]['mbox'])){ $authorMail = $this->instanceData[$instanceUri]['mbox'][0]['value']; } else { $authorMail = null; } if (isset($this->instanceData[$instanceUri]['zip'])) { $location = $this->instanceData[$instanceUri]['zip'][0]['uri']; } else { if(strpos($instanceUri, 'https://github.com/AKSW') === 0){ $location = implode('/', array_slice(explode('/', $instanceUri), 0, 5)) . '/zipball/master'; } else { $location = null; } } if(isset($this->instanceData[$instanceUri]['revision'])){ $revision = $this->instanceData[$instanceUri]['revision'][0]['value']; } else { $revision = null; } //only display the highest revision if(!isset($highestVersions[$name]) || $highestVersions[$name] != $revision){ continue; } $ow = OntoWiki::getInstance(); $manager = $ow->extensionManager; $configs = $manager->getExtensions(); $installed = $manager->isExtensionRegistered($name); $updateable = $installed && $location != null && $revision != null && version_compare($configs[$name]->version, $revision, '<'); ?>

          by  mail

          'exconf', 'action'=>'installarchiveremote')); $url->url = $location; $url->name = $name; $action = false; if(!$installed){ $label = 'install'; $action = true; } else if($updateable){ $label = 'update'; $action = true; } if($action){ ?>

          installed and up to date

          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 ================================================
        remove all filter
        definedfilters as $prop){ echo $prop["label"].":"; ?> ')">All $value){ if($key != "label" && $key != "uri"){ ?> ', false, '', 'equals', '', null, 'uri')">"; } ?>
        ================================================ FILE: extensions/filter/templates/filter/filter.phtml ================================================ translate; ?>

        filter) : ?> 'properties'), array('r')) ?> _('Active Filters') ?>:

        Add Filter

        equals
        or
        not
        set cancel
        ================================================ FILE: extensions/filter/templates/filter/getpossiblevalues.phtml ================================================ values as $value) : ?> values)) { echo 'Error: no values found '; } ?> ================================================ FILE: extensions/googletracking/GoogletrackingPlugin.php ================================================ _privateConfig->trackingID)) { $this->view->headScript()->appendScript( " var gaJsHost = ((\"https:\" == document.location.protocol) ? \"https://ssl.\" : \"http://www.\"); document.write(unescape(\"%3Cscript src='\" + gaJsHost + \"google-analytics.com/ga.js' type=" . "'text/javascript'%3E%3C/script%3E\"));" ); $this->view->headScript()->appendScript( " try { var pageTracker = _gat._getTracker(\"" . $this->_privateConfig->trackingID . "\"); pageTracker._trackPageview(); } catch(err) {}" ); } } } ================================================ FILE: extensions/googletracking/default.ini ================================================ enabled = false name = "Google Analytics" description = "A plug-in that adds a Google Analytics Tracking Code to every page." author = "Niederstätter Michael" [events] 1 = onAfterInitController [private] ;trackingID = "UA-XXXXXXX-8" ================================================ FILE: extensions/googletracking/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :googletracking . :googletracking a doap:Project ; doap:name "googletracking" ; owconfig:privateNamespace ; owconfig:enabled "false"^^xsd:boolean ; rdfs:label "Google Analytics" ; doap:description "A plug-in that adds a Google Analytics Tracking Code to every page." ; owconfig:authorLabel "Niederstätter Michael" ; owconfig:pluginEvent event:onAfterInitController ; doap:release :v1-0 . :v1-0 a doap:Version ; doap:revision "1.0" . ================================================ FILE: extensions/hideproperties/HidepropertiesPlugin.php ================================================ _privateConfig->hide->property) { $store = Erfurt_App::getInstance()->getStore(); $config = Erfurt_App::getInstance()->getConfig(); $data = $event->predicates; foreach ($data as $graphUri => $predicates) { $query = new Erfurt_Sparql_SimpleQuery(); $query->setSelectClause('SELECT DISTINCT *') ->addFrom((string)$graphUri) ->setWherePart('WHERE { ?p <' . $this->_privateConfig->hide->property . '> ?o . }'); $results = $store->sparqlQuery($query); if (!empty($results)) { $publicPredicates = Array(); foreach ($data as $element) { foreach ($element as $propertykey => $property) { $hide = false; foreach ($results as $result) { if ($result['p'] == $property['uri']) { $hide = true; break; } } if (!$hide) { $publicPredicates[$propertykey] = $property; } } } $data[$graphUri] = $publicPredicates; } } } $event->predicates = $data; return true; } } ================================================ FILE: extensions/hideproperties/default.ini ================================================ enabled = false name = HideProperties description = "A plug-in that hides defined Properties in the ressourceview" author = "Niederstaetter Michael , Maier Christian" [events] 1 = onPropertiesActionData [private] hide.property = "http://ns.ontowiki.net/SysOnt/hidden" ================================================ FILE: extensions/hideproperties/doap.n3 ================================================ @prefix xsd: . @prefix doap: . @prefix rdfs: . @prefix owconfig: . @prefix extension: . @prefix foaf: . @prefix event: . @prefix : . <> foaf:primaryTopic :hideproperties . :hideproperties a doap:Project ; doap:name "hideproperties" ; owconfig:privateNamespace ; owconfig:enabled "false"^^xsd:boolean ; rdfs:label "HideProperties" ; doap:description "A plug-in that hides defined Properties in the ressourceview" ; owconfig:authorLabel "Niederstaetter Michael , Maier Christian" ; owconfig:pluginEvent event:onPropertiesActionData ; owconfig:config [ a owconfig:Config; owconfig:id "hide"; :property