Need a solution that can scale both from small to large projects and we rather not reinvent the wheel!
PHPCR provides a standardized API that can be used by any PHP content management system to interface with any content repository.
* Not yet implemented in Jackalope-Jackrabbit
<jcr:root>
<cms>
<pages>
<home title="Hello">
<block title="News"
content="Today: PHPCR presentation"/>
</home>
<contact title="Contact"
content="phpcr-users@groups.google.com"/>
</pages>
</cms>
</jcr:root>
Source: phpcr.github.com
use PHPCR\SimpleCredentials;
// start of implementation specific configuration //
use Jackalope\RepositoryFactoryJackrabbit as Factory;
$parameters = array(
'jackalope.jackrabbit_uri'
=> 'http://localhost:8080/server',
);
$repository = Factory::getRepository($parameters);
// end of implementation specific configuration //
$creds = new SimpleCredentials('admin','admin');
$session = $repository->login($creds, 'default');
$root = $session->getRootNode();
// Nodes must be added as child of another node
$node = $root->addNode('test', 'nt:unstructured');
// New node is immediately available to this session
$node = $session->getNode('/test');
// Create/update a property
$node->setProperty('prop', 'value');
// New node is now available for all sessions
$session->save();
// Delete the node and all its children
$node->remove();
// Fails if a concurrent session also changed '/test'
$session->save();
$node = $session->getNode('/site/content');
foreach ($node->getNodes() as $child) {
var_dump($child->getName());
}
// or in short
foreach ($node as $child) {
var_dump($child->getName());
}
// filter on node names
foreach ($node->getNodes('di*') as $child) {
var_dump($child->getName());
}
// make versionable
$node = $session->getNode('/site/content/about');
$node->addMixin('mix:versionable');
$session->save();
// create initial version
$node->setProperty('title', 'About');
$session->save();
// check-in (create version)
// and check-out (prepare for further updates)
// persisted immediately without a save() call
$vm = $session->getWorkspace()->getVersionManager();
$vm->checkpoint($node->getPath());
// update node with some changes
$node->setProperty('title', 'Ups');
$session->save();
// create another version, leave in read only state
$vm->checkin($node->getPath());
$base = $vm->getBaseVersion($node->getPath());
$current = $base->getLinearPredecessor();
$previous = $current->getLinearPredecessor();
// get snapshot of old version to look around
$frozenNode = $previous->getFrozenNode();
echo $frozenNode->getProperty('title'); // About
// set the live data back to what is in this version
$vm->restore(true, $previous);
$node = $session->getNode('/site/content/about');
echo $node->getProperty('title'); // About
$qm = $workspace->getQueryManager();
// unlike SQL, in SQL2 "*" does not return all
// columns but at least the path and match score
$sql = "SELECT * FROM [nt:unstructured]
WHERE [nt:unstructured].type = 'nav'
AND ISDESCENDANTNODE('/some/path')
ORDER BY score, [nt:unstructured].title";
$query = $qm->createQuery($sql, 'JCR-SQL2');
$query->setLimit($limit);
$query->setOffset($offset);
$queryResult = $query->execute();
foreach ($queryResult->getNodes() as $node) {
var_dump($node->getPath());
}
(With phpcr-utils)
$qm = $workspace->getQueryManager();
$factory = $qm->getQOMFactory();
// SELECT * FROM nt:unstructured
// WHERE name NOT IS NULL
// LIMIT 10 OFFSET 10
$qb = new QueryBuilder($factory);
$qb->select($factory->selector('nt:unstructured'))
->where($factory->propertyExistence('name'))
->setFirstResult(10)
->setMaxResults(10)
->execute();
$test = $session->getNode('/test');
$test1 = $session1->getNode('/test');
$test->remove();
$test1->setProperty('prop', 'value');
$session->save();
// this will fail as the node is gone
$session1->save();
// prepare
$test = $session->getNode('/test');
$test->addMixin('mix:lockable');
$session->save();
// use
$lm = $session->getWorkspace()->getLockManager();
// lock node and children for 5 seconds
$lock = $lm->lock('/test', true, true, 5);
$test1 = $session1->getNode('/test');
// here you will get an exception that node is locked
$test1->setProperty('prop', 'value');
A test suite for PHPCR makes sure all implementations interpret the specification the same way.
Test results using Jackalope with the Jackrabbit backend.
......................................S.........S.....II..... 61 / 1222 ( 4%)
...........S.S............................................... 122 / 1222 ( 9%)
...........SS.......SS.S.......S............................. 183 / 1222 ( 14%)
............................................................. 244 / 1222 ( 19%)
............................................................. 305 / 1222 ( 24%)
............................................................. 366 / 1222 ( 29%)
............................................................. 427 / 1222 ( 34%)
..............................S.........SSS..............I.I. 488 / 1222 ( 39%)
I.I.........................I...................I..I........S 549 / 1222 ( 44%)
I............................................................ 610 / 1222 ( 49%)
.....S.......I.....................S..S...................... 671 / 1222 ( 54%)
.................SS...............SSSS..S.................... 732 / 1222 ( 59%)
.......................................................SSSSS. 793 / 1222 ( 64%)
..........................S.............I......S...........I. 854 / 1222 ( 69%)
.............................SS..................S........... 915 / 1222 ( 74%)
............................................................. 976 / 1222 ( 79%)
............................................................. 1037 / 1222 ( 84%)
...............................S............................. 1098 / 1222 ( 89%)
...........SSSS...........SSS................................ 1159 / 1222 ( 94%)
........................................SSSSSS............... 1220 / 1222 ( 99%)
.
Time: 03:23, Memory: 93.50Mb
OK, but incomplete or skipped tests!
Tests: 1212, Assertions: 6797, Incomplete: 17, Skipped: 49.
namespace Foo;
use Doctrine\ODM\PHPCR\Mapping as PHPCRODM;
/** @PHPCRODM\Document */
class Bar
{
/** @PHPCRODM\Id */
public $id;
/**
* @PHPCRODM\ParentDocument
*/
public $parent;
/** @PHPCRODM\Nodename */
public $nodename;
/** @PHPCRODM\String */
public $text;
}
// Create
$document = new Foo\Bar();
$document->parent = $dm->find(null, '/');
$document->nodename = 'test';
$document->text = 'Test text';
$dm->persist($document);
$dm->flush();
// Read
$document = $dm->find(null, '/test');
// Update
$document->text = 'foo!';
$dm->flush();
// Remove
$dm->remove($document);
$dm->flush();
/**
* Map the child node named the-logo
* @PHPCR\Child(name="the-logo")
*/
public $logo;
/**
* All child nodes starting with "a".
* @PHPCR\Children(filter="a*")
*/
public $children;
/** @PHPCR\ReferenceOne */
public $reference;
/** @PHPCR\Referrers */
public $referrers;
doctrine_phpcr:
# configure the PHPCR session
session:
backend:
type: doctrinedbal
connection: doctrine.dbal.default_connection
workspace: default
# enable the ODM layer
odm:
auto_mapping: true
auto_generate_proxy_classes: %kernel.debug%
locales:
en:
- en
- fr
fr:
- fr
- en
|
|
Please give me feedback:
@dbu on Twitter, or just david@liip.ch