Skip to content

php component requirement - version 1.0.1 released

Version 1.0.1 of Requirement Component for php is released. Changes are below.

  • Added annotations to example requirement
  • Added return value $this to magic __call methods of requirement and condition
  • Added return value $this to addItem method of ConditionInterface
  • Added return value $this to addCondition method of RequirementInterface
  • Added lock and isLocked method to RequirementInterface, RuntimeException is thrown if addCollection is called and requirement is locked
  • Updated Readme with explanation of provided examples

php component requirement - transfer business logic into code like a breeze

Reason Of Development

As a php developer, i have to deal with a lot of refactoring tasks day in and day out. Refactoring includes not only code refactoring but also business logic refactoring. A team member right now had figured out a general problem and we all knew that we have to put "the chaos into a cage" because of the following reasons:

  • Developers are lazy and want to call a simple method instead of rewriting complex expressions
  • After we found strange parts of code, we want to put that into a sentence to spot the business logic
  • We want to have a generic component where you can reuse business items
  • Since business logic can became nested, the component should handle this

After we (take a look to the credits please) tied up the requirements, it took some time to get a feeling of how to put this into classes. After a while, i had a longer talk with a team member and he presented me his idea. I liked his idea but found some drawbacks. Since it this is a normal way of coding, it really isn't a fault of the team member (and i'm also not a better programmer then he), but thats how this component was initial created. While i was on my way back home, i had some ideas how to keep things simple and generic and started that project. On the next day, jens joined me and we quickly made some progress and where able to tag version 1.0.0 pretty soon.

Common Terms And Names

To understand the component, it is worth to know about the used terms and names. We finally decided to use the following ones.

  • Requirement: Thats the class you want to work with. Extend it or use it straightaway via a factory. This class represents the business logic with all "and's" and "or's"
  • Condition: After reading and writing business logic, each is full of "or's" or '"and's". Thats why we provide two condition that are used to handle collections of business items (simple rules)
  • IsMetInterface: To keep it simple, when you implement a business logic or validate against one, you only want to know "is this requirement met or not", so thats what the interface is for. This interface is implemented in the Requirement as well as in the Condition and you have to implement it in your item as well
  • "()" are used to represent an and condition: ("foo", "bar") is "foo and bar"
  • "[]" are used to represent an or condition: ["foo", "bar"] is "foo or bar"

Example

The component is shiped with some examples. Feel free to pull some more. Nevertheless, to use this component, you have to do the following steps (and yes, this is already the example ;-)).

  • Try to sum things up by writing a sentence like: "The user mets our requirement if he is interested in OOP or big data and if he loves open source software, has no problem to read man pages or use his favorite internet searchengine or if he is already a maintainer or a contributor to an existing open source project"
  • Slice out the items that matters: "OOP", "big data", "loves open source", "read man pages", "use favorite internet searchengine", "maintainer", "contributor"
  • Create classes for each item that implements the IsMetInterface and that provides a usefull setter method
  • Collect the items into conditions: [(["OOP", "big data"], "loves open source"["read man pages", "use favorite internet searchengine"]), ["maintainer", "contributor"]]
  • Create the items and inject them to the right conditions, be aware of the fact that you even can inject conditions into conditions (meaning combine a condition with another)
  • Implement this into an class that extends the Requirement class or let it be assembled via a factory

Hints For Using And Developing

All in all you have to implement a setter method to your item. You can create setter methods in your requirement or simple use annotation. The requirement class and the condition classes are using the magic __call method to hand over the call from the requirement through the condition to the item.

If you want to create a requirement class that assembles itself or use a factory is a decision you have to make.

Download And Install

Github

git clone https://github.com/stevleibelt/php_component_requirement

Packagist.org

require: "net_bazzline/component_requirement": "dev-master"

Thanks

Thanks to Mihai Andrei Cosma - this is your idea, developed by ourselves :-).

PHP Component TestCase

I've finished writing unit tests for this component a few minutes ago so as the a beloved meme would say "things are getting pretty serious" ;-). It is possible i will tag the version "1.0.0" very soon.

What is this component for and where do i get it?
This component is considered as a starting point for creating question and answer test cases. Each test case has one question and one answer type. The current available types of answers are "single answer", "multiple answer" and "free text answer". All three types are using the same interface, so you can use them everywhere. You have to enter an answer to an answer (quite surprising right? ;-)) and the answer has the ability to tell you if your answer was the right one or how correct your current answer is.
The ideal wish is, that a lot of people are writing test cases for different subjects and you just simple use this component and the subjects to create your application or environment to use this test cases to, well, test people or yourself.
You can get the TestCase on github.com or via packagist.

A suite is also there to arrange multiple test cases under one subject. Since this component is using the Configuration Converter, everything can be written down as "YAML", "JSON" or "PHPArray". To illustrate this, you can write a "Suite.yaml" that points to a "TestCase.php" that is using a "Question.php" and a "Answer.yaml". The available factories can handle that if you want to.

The component itself is currently really basic so do not expect that finished "save the world" thing. But the test case stuff is started and truly open source.

php utilites lock and shutdown available

While i am dealing with cronjobs inside a private project, i run into some trouble with parallelism of cronjobs. A simple example would clear up this problem. Assume you have cronjob that generates cachefiles (like product descriptions or semi dynamic webcontent like cached rss feeds). You will end up by running a creation cronjob in an interval of x minutes. The problem that could happen is that a cronjob is already running while the next one is ready to go. You can deal with that problem by setting a maximum execution time in you script but this can lead into strange data and side effects. I want to solve this problem with two interfaces you can use. The first interface, called "Lock", is solving the problem with parallelism. If a lock is aquired you are not able to aquire a second one, meaning one cronjob not more. The second interface, called "Shutdown", is solving the problem with an early and controlled termination of a running cronjob. If the cronjob receives a shutdown, the cronjob can terminate itself i a good way. Both interfaces have a file based implementation. Unittests and also examples can be found inside the projects. The next idea I want to realize is an implementation of the Subject-Observer-Pattern. The general idea is that the first call of the cronjob is acting as a observer. The observer itself is chunking the work and split the work by calling (and observing) a number of cronjobs (of its own) as subjects.