Skip to content

Commit

Permalink
Merge pull request #7 from phonetworks/space
Browse files Browse the repository at this point in the history
Space
  • Loading branch information
esokullu authored Jun 22, 2017
2 parents ff5ec65 + a519e20 commit e2ee4cc
Show file tree
Hide file tree
Showing 11 changed files with 160 additions and 187 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,35 @@ The recommended way to install pho-framework is through composer.

Pho-Framework is built upon [pho-lib-graph](https://github.com/phonetworks/pho-lib-graph) to constitute the basis of the [Pho stack](https://github.com/phonetworks/). Readers should study pho-lib-graph before starting with Pho Framework.

With Pho, the framework nodes are called "particles" and they all implement [ParticleInterface](https://github.com/phonetworks/pho-framework/blob/master/src/Pho/Framework/ParticleInterface.php).
In Pho Framework, everything resides in Space, which is a direct extension of pho-lib-graph's Graph class. The framework nodes are called "particles" and they all must implement [ParticleInterface](https://github.com/phonetworks/pho-framework/blob/master/src/Pho/Framework/ParticleInterface.php).

There are three types of particles:

1. Actor
2. Frame
2. Graph (which is the equivalent of pho-lib-graph's SubGraph)
3. Object

You may wonder why we've created confusion by renaming pho-lib-graph's Graph and SubGraph classes as Space and Graph respectively. That's because Graph and SubGraph are general Graph Theory concepts, which we didn't want to touch, and pho-lib-graph is meant to be a general-purpose graph theory library. On the other hand, in Pho universe, a social network itself is a **graph** that exists in a **space** along with many other social networks. In other words, a social network is a subgraph of the Space; e.g. Facebook is a subgraph of the Space, Twitter is a subgraph of the Space, and the list goes on. Calling all these networks, along with their subgraphs (think of Facebook Groups, Facebook Events, Twitter Lists, your contact list on Snapchat etc.) would create redundancy of the prefix "sub", hence we decided to call them all "graphs" and use the terms "subgraph" and "supergraph" to determine their positioning in respect to each other within the Pho universe.

### Actor
An actor does three things;

* read
* write
* subscribe

### Frame
Frame extends the SubGraph class of pho-lib-graph. Therefore it shows both graph and node properties. It does only one thing;
### Graph
Graph extends the SubGraph class of pho-lib-graph. Therefore it shows both graph and node properties. It does only one thing;
* contain

### Object
Object is what graph actors consume, and are centered around. Objects have one and only one edge:
* transmit

To illustrate what these particles do, with real-world examples;
To illustrate what these particles do with real-world examples;

* Users, admins and anonymous users of apps, social networks are **Actors**. They _do_ things; ready, write, subscribe.
* Groups, events and social networks are **Frames**. They are recursive social graphs, they _contain_ Actors.
* Groups, events and social networks, friend lists are **Graphs**. They are recursive social graphs, they _contain_ Actors.
* Blog posts, status updates, Snaps, Tweets are all **Objects**. They are what social network members (Actors) are centered around. They optionally do one and only one thing; that is to _transmit_. For example, a private message is an object that _transmits_ to a certain actor, while a blog post is not.

## Architecture
Expand Down Expand Up @@ -83,7 +85,7 @@ For an edge to be valid, it must:
* TAIL_LABELS: same as above, in plural. So it's "subscribers"
* HEAD_LABEL: what the head node of this edge's role is called, in singular. A subscriber subscribes to a *subscription*, hence it's "subscription"
* HEAD_LABELS: same as above, in plural. So it's "subscriptions"
* SETTABLES: what classes can this edge target, in array format. If it's [Framework\ParticleInterface::class], that means it can target any node/particle. Sometimes this level of flexibility may not be the case for all types of edges; for example, the [Write](https://github.com/phonetworks/pho-framework/blob/master/src/Pho/Framework/ActorOut/Write.php) edge cannot target Actor particles, because a user can't create a user. Hence its SETTABLES is declared as [Framework\Object::class, Framework\Frame::class] only, so that it can target Frames and Objects only, and not Actors.
* SETTABLES: what classes can this edge target, in array format. If it's [Framework\ParticleInterface::class], that means it can target any node/particle. Sometimes this level of flexibility may not be the case for all types of edges; for example, the [Write](https://github.com/phonetworks/pho-framework/blob/master/src/Pho/Framework/ActorOut/Write.php) edge cannot target Actor particles, because a user can't create a user. Hence its SETTABLES is declared as [Framework\Object::class, Framework\Graph::class] only, so that it can target Graphs and Objects only, and not Actors.

As you can see above, the constants defined in the edge class are merely for naming purposes. The mechanics function as follows;

Expand All @@ -107,7 +109,7 @@ $actor->getSubscriptions();

Pho-Framework is built upon pho-lib-graph which has extensive support for hydration that can be used for several applications such as persistence. Pho-Framework adds up to that, by adding a new hydrating function ```hydratedCreator()```.

* **hydratedCreator()**: called when ```creator()``` can't find the creator. Enables you to access ```$creator_id``` to fetch it from external sources. This can be used with any particle; be it an Actor, Object or Frame. The return value is **Actor**.
* **hydratedCreator()**: called when ```creator()``` can't find the creator. Enables you to access ```$creator_id``` to fetch it from external sources. This can be used with any particle; be it an Actor, Object or Graph. The return value is **Actor**.

Also the following functions may be overridden with hydrating functions otherwise the program may not perform well at scale given the fact that the current implementation works by recursing through each and every edge of the given node.

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4.7.0
5.0.0
2 changes: 1 addition & 1 deletion src/Pho/Framework/ActorOut/Write.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ class Write extends Subscribe
const HEAD_LABELS = "writes";
const TAIL_LABEL = "writer";
const TAIL_LABELS = "writers";
const SETTABLES = [Framework\Frame::class, Framework\Object::class]; /* inherits the values in Edits */
const SETTABLES = [Framework\Graph::class, Framework\Object::class]; /* inherits the values in Edits */

}
4 changes: 2 additions & 2 deletions src/Pho/Framework/ContextInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ interface ContextInterface extends \Pho\Lib\Graph\GraphInterface
{

/**
* Checks if the given context is equal to or a subelement of this context.
* Checks if the given context is contained by or equal to this graph.
*
* @param ContextInterface $context
* @return bool
*/
public function belongsOrEquals(ContextInterface $context): bool;
public function in(ContextInterface $context): bool;

}
69 changes: 0 additions & 69 deletions src/Pho/Framework/Frame.php

This file was deleted.

82 changes: 43 additions & 39 deletions src/Pho/Framework/Graph.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,57 +12,61 @@
namespace Pho\Framework;

/**
* The Graph
* The Frame Particle
*
* This class is a shell to Pho\Lib\Graph's Graph implementation
* and it implements ContextInterface to give higher-level
* software access to use both Frame and Graph as context objects.
* At its core, Frame is a graph, or more specifically, a subgraph.
* It extends the Pho\Lib\Graph\SubGraph class, which is a regular node,
* as well as a Graph (by way of using the Pho\Lib\Graph\ClusterTrait)
* both at the same time. It implements both Pho\Lib\Graph\GraphInterface
* and Pho\Lib\Graph\NodeInterface. In order to prevent
* any confusions with Pho\Lib\Graph's nomenclature, this class is called
* Frame instead.
*
* In contrast to other particles, Frame doesn't contain edges but
* its **"contains"** method acts similarly to an edge.
*
* @author Emre Sokullu <[email protected]>
*/
class Graph extends \Pho\Lib\Graph\Graph implements ContextInterface
class Graph extends \Pho\Lib\Graph\SubGraph implements ParticleInterface, ContextInterface
{

/**
* The title of the graph.
*
* @var string
*/
protected $title;

/**
* Constructor.
*
* The title allows one to host multiple graphs in a single PHP instance.
*
* @param string $title Optional. Leave blank for a random title.
*/
public function __construct(string $title = "")
{
if(empty($title)) {
$this->title = uniqid("graph_", true);
}
else {
$this->title = $title;
}
use ParticleTrait {
ParticleTrait::__construct as particleConstructor;
}

/**
* Returns the title of the graph.
*
* @return string
*/
public function title(): string
public function __construct(Actor $creator, ContextInterface $context)
{
return $this->title;
parent::__construct($context);
$this->creator = $creator;
$this->creator_id = (string) $creator->id();
$this->registerIncomingEdges(ActorOut\Write::class);
$this->particleConstructor();
}

/**
* {@inheritdoc}
*/
public function belongsOrEquals(ContextInterface $context): bool
/**
* {@inheritdoc}
*/
public function in(ContextInterface $context): bool
{
return $context instanceof Graph && $this->title == $context->title();
/*
// would speed up, but not good for testing.
if($context instanceof Space)
return true;
*/
$members = $context->members();
foreach($members as $member) {
if($member instanceof Graph) {
if($member->id() == $this->id()) {
return true;
}
else {
if($this->in($member)) {
return true;
}
}
}
}
return false;
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
## Important Note

In contrast to Actor and Object, Frame has no regular edges built-in.
In contrast to Actor and Object, Graph has no regular edges built-in.

Frame extends Pho\Lib\SubGraph, hence comes with the **"contains"**
Graph extends Pho\Lib\SubGraph, hence comes with the **"contains"**
method which is a quasi-edge, but not quite.

Nevertheless, Frame is a node *-- in the sense that it implements both
Nevertheless, Graph is a node *-- in the sense that it implements both
Pho\Lib\Graph\NodeInterface and Pho\Framework\ParticleInterface--* as well as
a subgraph (with Pho\Lib\Graph\ClusterTrait) both at the same time.

Expand Down
33 changes: 33 additions & 0 deletions src/Pho/Framework/Space.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/*
* This file is part of the Pho package.
*
* (c) Emre Sokullu <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Pho\Framework;

/**
* The Space
*
* This class is a shell to Pho\Lib\Graph's Graph implementation
* and it implements ContextInterface to give higher-level
* software access to use both Frame and Graph as context objects.
*
* @author Emre Sokullu <[email protected]>
*/
class Space extends \Pho\Lib\Graph\Graph implements ContextInterface
{
/**
* {@inheritdoc}
*/
public function in(ContextInterface $context): bool
{
return $context instanceof Space;
}

}
6 changes: 3 additions & 3 deletions tests/Pho/Framework/LoggerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@

class LoggerTest extends \PHPUnit\Framework\TestCase
{
private $graph;
private $space;

public function setUp() {
$this->graph = new Graph();
$this->space = new Space();
\Pho\Lib\Graph\Logger::setVerbosity(2);
}

Expand All @@ -29,7 +29,7 @@ public function tearDown() {

public function testLogging() {
ob_start();
$node = new Actor($this->graph);
$node = new Actor($this->space);
$output = ob_get_clean();
$expected = "A node with id \"";
$this->assertEquals($expected, substr($output,0,strlen($expected)));
Expand Down
Loading

0 comments on commit e2ee4cc

Please sign in to comment.