Within the Saft project we have some conventions which should help us during the development process.

Implementation conventions

Handling and storing of constructor parameters

That convention affects all implementations of a Saft interface. If you pass a parameter to the constructor and want to save later on, it must be stored in a private property. Saft interfaces do not specify how to initialize a class, because of that, you can not be sure to be able to re-use certain properties, if you create a subclass of such a class. Sure, you can look into the class you wanna create a subclass from, but there has to be a standard way, if you can rely on the usage of such properties or not. We decided, that you can not.

Example

Here is some example code:

<?php

class Foo
{
    private $bar;
    public function __construct($bar)
    {
        $this->bar = $bar;
    }
}

Coding Standard and Coding Style

Within the PHP code we are following the PHP Standard Recommendation (PSR) for Basic Coding Standard (PSR-1) and for Coding Style Guide (PSR-2). If you are seeing violations to those standards (e.g. by checking the code with codesniffer) please correct them and commit them in a separate commit containing the words “fix coding standard” or “fix coding style” in the git commit message. Such commits should contain pure coding standard resp. coding style changes and should not be mixed with functional changes.

Naming conventions

Naming in Saft is relevant in different contexts. There are the general names, which are used throughout this documentation and for the repos on github. There are names used for the composer packages and we have to handle the namespaces in the PHP-code as well as class names for interface, abstract classes and implementations.

general names

All packages within the Saft project are prefixed by Saft. The name of the package and its subpackages are separated by a dot, e.g. Saft.store (the store interface and co) and Saft.store.virtuoso (the store implementation using virtuoso backend). Theses names are used for the git repositories as github and for the general communication.

Alternative Proposal create a flat naming schema here, e.g. Saft.redland, because in this case redland implements interfaces from Saft.store as well as Saft.rdf and Saft.data.

Alternative Proposal reflect the namespace scheme here and use Saft.backend.redland resp. Saft.backend.virtuoso, while one has to look into the packages to see which parts the backend actually is implementing

composer names

The composer packages have to align with the suggestions made in the composer documentation. Thus we can’t use our general names. The composer packages should have names like saft/saft-rdf. All lower case, and using the dash - as word separator (instead of the .).

PHP namespaces

All namespaces in the Saft project start with the PHP-namespace \Saft\ under this namespace all classes in the subpackages are followed by the subpackage name, e.g \Saft\Rdf\ (string with an upper case letter).

For backend implementations distributed under the \Saft\ namespace you should use \Saft\Backend\<name of the implementation> e.g. \Saft\Backend\Virtuoso\…. If you are developing your own backend your are safe if you are putting it under your own namespace.

The namespace structure should be reflected on the filesystem level.

  • \Saft\
    • Rdf\
    • Data\
    • Store\
    • Sparql\
    • Addition\
      • Name of the implementation\
        • Rdf\
        • Data\
        • Store\
        • Custom Subpackages\

PHP Interfaces, Abstract Classes and Implementation

Currently under discussion

If we have a concept (e.g. Statement, Store) we want to support with Saft we are implementing it as follows: The Structure is expressed in an interface, method which are common to all or some defined set of implementations of the concept are implemented in an abstract class. If we also want to provide some basic implementation of the interface we should try to keep the system requirements as low as possible and only use standard PHP functions.

The abstract class should try to make as view assumptions about the implementations and should only communicate with the implemantation via methods, which are implemented by the implementation.

The naming of those items is as follows, using the example of the

  • Statement: interface Statement,
  • abstract class AbstractStatement implements Statement and
  • class StatementImpl extends AbstractStatement.

Or looking at the Store it should be

  • interface Store,
  • abstract class AbstractSparqlStore implements Store vs. abstract class AbstractTriplePatternStore implements StoreInterface and e.g.
  • class ArrayStoreImpl extends AbstractTriplePatternStore.

Test Cases

If you write test cases for Saft, please follow these conventions:

  • TestCases: Group test functions together, if they test the same function
  • TestCases: Alphabetical order of groups of test functions.
  • Alphabetical order for use-statements.

These improve readability and make it easier to find tests for a certain method. If the method are spread out over the whole document, its very hard to keep track, what cases for the method were tested and which not. That will be even more difficult, if that is not your code.