Function and variables issue - php

I have a problem.. When I execute this code:
public function korisnici(){
$modelk = new Korisnici();
$upit = $modelk::find()->asArray()->orderBy('id DESC')->all();
$items = [];
foreach ($upit as $key => $value) {
foreach ($value as $kljuc => $vrijednost){
$items[] = [$kljuc => $vrijednost];
}
}
return $items;
}
private static $users = $this->korisnici();
It gives me this error: syntax error, unexpected '$this' (T_VARIABLE)..
Can someone help me, how can I call this function?
Here's my whole class:
class User extends \yii\base\Object implements \yii\web\IdentityInterface
{
public $id;
public $username;
public $password;
public $authKey;
public $accessToken;
public $arr;
public function korisnici(){
$modelk = new Korisnici();
$upit = $modelk::find()->asArray()->orderBy('id DESC')->all();
$items = [];
foreach ($upit as $key => $value) {
foreach ($value as $kljuc => $vrijednost){
$items[] = [$kljuc => $vrijednost];
}
}
return $items;
}
public $users = $this->korisnici();
/**
* #inheritdoc
*/
public static function findIdentity($id)
{
return isset(self::$users[$id]) ? new static(self::$users[$id]) : null;
}
/**
* #inheritdoc
*/
public static function findIdentityByAccessToken($token, $type = null)
{
foreach (self::$users as $user) {
if ($user['accessToken'] === $token) {
return new static($user);
}
}
return null;
}
/**
* Finds user by username
*
* #param string $username
* #return static|null
*/
public static function findByUsername($username)
{
foreach (self::$users as $user) {
if (strcasecmp($user['username'], $username) === 0) {
return new static($user);
}
}
return null;
}
/**
* #inheritdoc
*/
public function getId()
{
return $this->id;
}
/**
* #inheritdoc
*/
public function getAuthKey()
{
return $this->authKey;
}
/**
* #inheritdoc
*/
public function validateAuthKey($authKey)
{
return $this->authKey === $authKey;
}
/**
* Validates password
*
* #param string $password password to validate
* #return boolean if password provided is valid for current user
*/
public function validatePassword($password)
{
return $this->password === $password;
}
}
I'm trying to change this default model from Yii Framework so I can login using database...

Looks like you have copied it from a class. The following will work like a regular function. Still not sure where you get $modelk = new Korisnici(); from
function korisnici(){
$modelk = new Korisnici();
$upit = $modelk::find()->asArray()->orderBy('id DESC')->all();
$items = [];
foreach ($upit as $key => $value) {
foreach ($value as $kljuc => $vrijednost){
$items[] = [$kljuc => $vrijednost];
}
}
return $items;
}
print_r(korisnici());
EDIT: After looking at your whole class:
You need to use the __construct method.
public function __construct()
{
$this->users = $this->korisnici();
}

Related

SQL request or php solution to manage employers

My entity :
class User{
id : int
name : string
boss : User()
}
I want to create a function that return an array() of users that work under a giving user.
example :
public function MyEmployers( User $user , array $usersList )
{
$myEmployers = array();
...
return $myEmployers;
}
$results = $this->myEmployers ( $employer1 , $allEmployers)
dump ( $results );
$results = [ 4 , 5 , 6 ];
I found a solution if someone can improve it feel free :
public $tree = array();
public function MyEmployers(User $user)
{
$superior_key_id = array();
$all_users = $this->getallusers();
$id = $user->getId();
foreach ($all_users as $user) {
if ($user->getSuperior())
$superior_key_id[$user->getSuperior()->getId()][] = $user;
}
$this->getSubEmployee($this->getUser(), $superior_key_id);
return ($this->tree);
}
public function getSubEmployee($user, $superior_key_id)
{
if (isset($superior_key_id[$user->getId()])) {
foreach ($superior_key_id[$user->getId()] as $user) {
$this->tree[] = $user;
$this->getSubEmployee($user, $superior_key_id);
}
}
return $user;
}
this one will get all bosses if you're interested :
public function MyBosses(User $user)
{
$bosses = array();
while ($user->getSuperior()) {
array_push($bosses, $user->getSuperior());
$user = $user->getSuperior();
}
return $bosses;
}
You could set up a one-to-many relationship between boss and employee
So you're user class could look like:
class User{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="employee")
*/
private $boss;
/**
* #ORM\OneToMany(targetEntity="App\Entity\User", mappedBy="boss")
*/
private $employees;
public function __construct()
{
$this->employees = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
/**
* #return Collection|employees[]
*/
public function getEmployees(): Collection
{
return $this->employees;
}
public function addEmployee(employee $employee): self
{
if (!$this->employees->contains($employee)) {
$this->employees[] = $employee;
}
return $this;
}
public function removeEmployee(employee $employee): self
{
if ($this->employees->contains($employee)) {
$this->employees->removeElement($employee);
}
return $this;
}
public function getBoss(): ?Usesr
{
return $this->boss;
}
public function setBoss(?User $boss): self
{
$this->boss = $boss;
return $this;
}
}
You would need to set up the database relationship with the symfony make:entity command.
To get all employeers under a user, you could do something like:
function getAllEmployeesUnder(User $user)
{
$allEmployees = [];
foreach ($user->getEmployees as $employee) {
$allEmployees[] = $employee;
$allEmployees = array_merge($allEmployees, $this->getAllEmployeesUnder($employee));
}
return $allEmployees;
}

laravel map model properties

Is it possible with laravel to retrieve a model property when using $queryBuilder->get() method ?
My database have weird naming convention (old app), and I have written one get*Attribute() method for each field, so I can access it by doing $model->prettyName, instead of $model->weird_Convention_Name, but when I use the $queryBuilder->get(), I get the database field, not the model properties.
Is there a way of doing this ?
EDIT
Here a sample of code:
Model
<?php
namespace Model\Day;
use Illuminate\Database\Eloquent\Builder;
/**
* Class Incomplete
* #package Model
* #subpackage Day
* #property string $alarm
* #property string $status
* #property string $mark1
* #property int $dayRate
* #property bool $isHalfDay
* #property bool $noPause
* #property bool $isTracked
* #property bool $noTime
* #property string $dayType
* #property string $shortDay
* #property \DateTime $date
* #property \DateTime $startDay
* #property \DateTime $startBreak
* #property \DateTime $endBreak
* #property \DateTime $startBreak2
* #property \DateTime $endBreak2
* #property \DateTime $endDay
* #property string $statusDescription
* #property string $subtype
* #property string $subcode
* #property string $description
* #property int $locationId
* #property string $locationDes
*
* #method \Eloquent currentUser()
*/
class Incomplete extends \Eloquent
{
/**
* The database table used by the model.
* #var string
*/
protected $table = 'vlogger_pending';
/**
* The primary key for the model.
* #var string
*/
protected $primaryKey = null;
/**
* The sequence name used for incrementing
* #var string
*/
protected $sequence = null;
/**
* Indicates if the IDs are auto-incrementing.
* #var bool
*/
public $incrementing = false;
/**
* Indicates if the model should be timestamped.
* #var bool
*/
public $timestamps = false;
/***********************************************************************
* SCOPES
***********************************************************************/
/**
* Add a where statement for current logged in user
* #param Builder $query
* #return Builder
*/
public function scopeCurrentUser(Builder $query)
{
return $query->where('usr_id', '=', \Auth::user()->id);
}
/***********************************************************************
* ACCESSORS
***********************************************************************/
public function getAlarmAttribute()
{
return $this->attributes['alarm'];
}
public function getStatusAttribute()
{
return $this->attributes['status'];
}
public function getMark1Attribute()
{
return $this->attributes['mark1'];
}
public function getDayRateAttribute()
{
return (int)$this->attributes['day_rate'];
}
public function getIsHalfDayAttribute()
{
return !!$this->attributes['half_day'];
}
public function getNoPauseAttribute()
{
return !!$this->attributes['no_pause'];
}
public function getIsTrackedAttribute()
{
return !!$this->attributes['tracked'];
}
public function getNoTimeAttribute()
{
return !!$this->attributes['no_hours'];
}
public function getDayTypeAttribute()
{
return $this->attributes['day_type'];
}
public function getShortDayAttribute()
{
return $this->attributes['dd'];
}
public function getDateAttribute()
{
$date = $this->attributes['day'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getStartDayAttribute()
{
$date = $this->attributes['dstart'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getStartBreakAttribute()
{
$date = $this->attributes['pstart'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getEndBreakAttribute()
{
$date = $this->attributes['pend'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getStartBreak2Attribute()
{
$date = $this->attributes['s_pstart2'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getEndBreak2Attribute()
{
$date = $this->attributes['s_pend2'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getEndDayAttribute()
{
$date = $this->attributes['dend'];
if (null !== $date) {
$date = \DateTime::createFromFormat('U', strtotime($date));
}
return $date;
}
public function getStatusDescriptionAttribute()
{
return $this->attributes['status_des'];
}
public function getSubtypeAttribute()
{
return $this->attributes['sub_type'];
}
public function getSubcodeAttribute()
{
return $this->attributes['sub_code'];
}
public function getDescriptionAttribute()
{
return $this->attributes['des'];
}
public function getLocationIdAttribute()
{
return (int)$this->attributes['location'];
}
public function getLocationDesAttribute()
{
return $this->attributes['location_des'];
}
/***********************************************************************
* MUTATORS
***********************************************************************/
public function setAlarmAttribute($value)
{
$this->attributes['alarm'] = $value;
return $this;
}
public function setStatusAttribute($value)
{
$this->attributes['status'] = $value;
return $this;
}
public function setMark1Attribute($value)
{
$this->attributes['mark1'] = $value;
return $this;
}
public function setDayRateAttribute($value)
{
$this->attributes['day_rate'] = $value;
return $this;
}
public function setIsHalfDayAttribute($value)
{
$this->attributes['half_day'] = $value;
return $this;
}
public function setNoPauseAttribute($value)
{
$this->attributes['no_pause'] = $value;
return $this;
}
public function setIsTrackedAttribute($value)
{
$this->attributes['tracked'] = $value;
return $this;
}
public function setNoTimeAttribute($value)
{
$this->attributes['no_hours'] = $value;
return $this;
}
public function setDayTypeAttribute($value)
{
$this->attributes['day_type'] = $value;
return $this;
}
public function setShortDayAttribute($value)
{
$this->attributes['dd'] = $value;
return $this;
}
public function setDateAttribute($value)
{
$this->attributes['day'] = $value;
return $this;
}
public function setStartDayAttribute($value)
{
$this->attributes['dstart'] = $value;
return $this;
}
public function setStartBreakAttribute($value)
{
$this->attributes['pstart'] = $value;
return $this;
}
public function setEndBreakAttribute($value)
{
$this->attributes['pend'] = $value;
return $this;
}
public function setStartBreak2Attribute($value)
{
$this->attributes['s_pstart2'] = $value;
return $this;
}
public function setEndBreak2Attribute($value)
{
$this->attributes['s_pend2'] = $value;
return $this;
}
public function setEndDayAttribute($value)
{
$this->attributes['dend'] = $value;
return $this;
}
public function setStatusDescriptionAttribute($value)
{
$this->attributes['status_des'] = $value;
return $this;
}
public function setSubtypeAttribute($value)
{
$this->attributes['sub_type'] = $value;
return $this;
}
public function setSubcodeAttribute($value)
{
$this->attributes['sub_code'] = $value;
return $this;
}
public function setDescriptionAttribute($value)
{
$this->attributes['des'] = $value;
return $this;
}
public function setLocationIdAttribute($value)
{
$this->attributes['location'] = $value;
return $this;
}
public function setLocationDesAttribute($value)
{
$this->attributes['location_des'] = $value;
return $this;
}
}
Controller
/**
* Get pending report for current logged user
* #return \Illuminate\Http\JsonResponse
*/
public function pendingReport()
{
return Response::json(Day\Incomplete::currentUser()->get());
}
Set $snakeAttributes in your model to false to use prettyName.
And use $appends to add formatted attribute when convert data to json.
class MyModel extends Eloquent {
public static $snakeAttributes = false;
protected $hidden = array('oldAttribute1', 'oldAttribute2');
protected $appends = array('attribute1', 'attribute2');
public function getAttribute1Attribute()
{
return 'Attribute1 Value';
}
public function getAttribute2Attribute()
{
return 'Attribute2 Value';
}
}
You can use "magick" __get():
private $aliases = array('
'prettyName' => 'weird_Convention_Name',
//...
');
public function __get($key)
{
if (!empty($this->aliases[$key]))
return parent::__get($this->aliases[$key]);
else
return parent::__get($key);
}
and always when you use $model->prettyName it return $model->weird_Convention_Name

Update a record through model in zend framework

I am having a model and would need to update the record. every time $count ($count = $post->save()) is being NULL. how is it possible to know whether this record saved or not. if saved, i want to display the following message 'Post updated' and if not the other message 'Post cannot update'.
This is always going to the else port. how can i know model updated correctly or not?
$post = new Application_Model_Post($form->getValues());
$post->setId($id);
$count = $post->save();
//var_dump($count); exit;
if ($count > 0) {
$this->_helper->flashMessenger->addMessage('Post updated');
} else {
$this->_helper->flashMessenger->addMessage('Post cannot update');
}
Application_Model_Post code is as below,
class Application_Model_Post
{
/**
* #var int
*/
protected $_id;
/**
* #var string
*/
protected $_title;
/**
* #var string
*/
protected $_body;
/**
* #var string
*/
protected $_created;
/**
* #var string
*/
protected $_updated;
/**
* #var Application_Model_PostMapper
*/
protected $_mapper;
/**
* Class Constructor.
*
* #param array $options
* #return void
*/
public function __construct(array $options = null)
{
if (is_array($options)) {
$this->setOptions($options);
}
}
public function setOptions(array $options)
{
$methods = get_class_methods($this);
foreach ($options as $key=> $value) {
$method = 'set'.ucfirst($key);
if (in_array($method, $methods)) {
$this->$method($value);
}
}
return $this;
}
public function setId($id)
{
$this->_id = $id;
return $this;
}
public function getId()
{
return $this->_id;
}
public function setTitle($title)
{
$this->_title = (string) $title;
return $this;
}
public function getTitle()
{
return $this->_title;
}
public function setBody($body)
{
$this->_body = $body;
return $this;
}
public function getBody()
{
return $this->_body;
}
public function setCreated($ts)
{
$this->_created = $ts;
return $this;
}
public function getCreated()
{
return $this->_created;
}
/**
* Set data mapper.
*
* #param mixed $mapper
* #return Application_Model_Post
*/
public function setMapper($mapper)
{
$this->_mapper = $mapper;
return $this;
}
/**
* Get data mapper.
*
* Lazy loads Application_Model_PostMapper instance if no mapper
* registered.
*
* #return Application_Model_PostMapper
*/
public function getMapper()
{
if (null === $this->_mapper) {
$this->setMapper(new Application_Model_PostMapper());
}
return $this->_mapper;
}
/**
* Save the current post.
*
* #return void
*/
public function save()
{
$this->getMapper()->save($this);
}
public function getPost($id)
{
return $this->getMapper()->getPost($id);
}
/**
* Update the current post.
*
* #return void
*/
public function update($data, $where)
{
$this->getMapper()->update($data, $where);
}
/**
* Find a post.
*
* Resets entry state if matching id found.
*
* #param int $id
* #return Application_Model_Post
*/
public function find($id)
{
$this->getMapper()->find($id, $this);
return $this;
}
/**
* Fetch all posts.
*
* #return array
*/
public function fetchAll()
{
return $this->getMapper()->fetchAll();
}
}
getMapper refers to the class Application_Model_PostMapper.
class Application_Model_PostMapper
{
public function save(Application_Model_Post $post)
{
$data = array(
'title'=>$post->getTitle(),
'body'=>$post->getBody(),
'created'=>$post->getCreated()
);
if (null === ($id = $post->getId())) {
unset($data['id']);
$data['created'] = date('Y-m-d H:i:s');
$post->setId($this->getDbTable()->insert($data));
} else {
$this->getDbTable()->update($data, array('id = ?'=>$id));
}
}
public function getDbTable()
{
if (null === $this->_dbTable) {
$this->setDbTable('Application_Model_DbTable_Post');
}
return $this->_dbTable;
}
}
Class of Application_Model_DbTable_Post
class Application_Model_DbTable_Post extends Zend_Db_Table_Abstract
{
protected $_name = 'posts';
}
Let me know if anything is incorrect. i am a newbie to zend and did thsi while referring the zend site. http://framework.zend.com/manual/1.12/en/learning.quickstart.create-model.html
you can extend your script like this. zend dbtable triggers the Zend_Db_Exception on any error during any insert or update.
class Application_Model_PostMapper
{
public function save(Application_Model_Post $post)
{
$data = array(
'title'=>$post->getTitle(),
'body'=>$post->getBody(),
'created'=>$post->getCreated()
);
try {
if (null === ($id = $post->getId())) {
unset($data['id']);
$data['created'] = date('Y-m-d H:i:s');
$post->setId($this->getDbTable()->insert($data));
} else {
$this->getDbTable()->update($data, array('id = ?'=>$id));
}
} catch (Zend_Db_Exception $e) {
// error thrown by dbtable class
return $e->getMessage();
}
// no error
return true;
}
}
now you can check like this
$post = new Application_Model_Post($form->getValues());
$post->setId($id);
$isSaved = $post->save();
if ($isSaved === true) {
$this->_helper->flashMessenger->addMessage('Post updated');
} else {
// error
// $isSaved holds the error message
$this->_helper->flashMessenger->addMessage('Post cannot update');
}

How can i do this right? PHP5 Form validation

I'm trying to set my first steps into the OO PHP world. What I'm trying to do is make a class that validates my form input. I know what input fields I need in my entire website and want to make a switch, to do the right thing based on the input field. Lets say we have the input field named 'email', and we have a form for that etc...
First, what I want to do is try to read the $_post names with array_key() function, based on that I have a switch.
Here is my code:
public function __construct ( $var ) {
$this->arraykeys = array_keys($var);
$this->error = false;
$this->message = array();
}
public function check() {
foreach ($this->arraykeys as $i => $value)
{
switch ($value)
{
case 'email' :
$checkmail = new checkEmail($_POST);
$checkmail->chkEmail($_POST['email']);
if ($checkmail->chkEmail($_POST['email']) == false)
{
array_push($this->message, 'Cannot validate emailadres');
}
break;
}
}
// print_r($this->field);
}
The check works, but somehow the message array stays empty after an error!
I tried everything, but I just can't get it on to the screen!
Please help!
Thanks!!
Before you make use of OOP you actually need to have some of the more basic objects that enable you to let your form processing come to live, for example object oriented validation of form fields within PHP superglobals with error messages:
Just exemplary:
// defining the interfaces and classes of the form values and validation, form field
// and fields
Interface FormValue
{
public function getValue();
}
interface FormValueValidator
{
/**
* #param FormValue $value
* #return bool
*/
public function validate(FormValue $value);
}
class NamedFormValue implements FormValue
{
private $name;
private $value;
public function __construct(array $data, $name, $default = null)
{
$this->name = $name;
$this->value = isset($data[$name]) ? $data[$name] : $default;
}
public function getValue()
{
return $this->value;
}
public function getName()
{
return $this->name;
}
}
class EmailValidator implements FormValueValidator
{
public function validate(FormValue $value)
{
$result = filter_var((string) $value->getValue(), FILTER_VALIDATE_EMAIL);
return is_string($result);
}
}
class FormFieldFactory
{
/**
* #param $name
* #param array $field
* #return FormField
*/
public function create($name, array $field)
{
$validatorClass = sprintf('%sValidator', #$field['validator']);
$validator = new $validatorClass;
$formField = new FormField($name);
$formField->setValidator($validator);
$formField->setErrorMessage($field['error_msg']);
return $formField;
}
}
class FormField
{
private $name;
/**
* #var FormValueValidator
*/
private $validator;
private $errorMessage;
/**
* #var FormValue
*/
private $value;
public function __construct($name)
{
$this->name = $name;
}
public function setValidator(FormValueValidator $validator)
{
$this->validator = $validator;
}
public function isValid()
{
return $this->validator->validate($this->value);
}
public function setErrorMessage($errorMessage)
{
$this->errorMessage = $errorMessage;
}
public function getErrorMessage() {
return $this->errorMessage;
}
public function setValue(FormValue $value)
{
$this->value = $value;
}
/**
* #return FormValue
*/
public function getValue()
{
return $this->value;
}
}
class FormFields extends IteratorIterator
{
private $fieldFactory;
private $invalidFields;
public function __construct(array $definitions, $fieldFactory)
{
parent::__construct(new ArrayIterator($definitions));
$this->fieldFactory = $fieldFactory;
}
public function current()
{
$name = $this->getInnerIterator()->key();
$definition = $this->getInnerIterator()->current();
return $this->fieldFactory->create($name, $definition);
}
public function valid()
{
return $this->getInnerIterator()->valid();
}
/**
* #param array $data
* #return bool true on success, false on validation error
*/
public function validateOn(array $data)
{
$this->invalidFields = array();
foreach($this as $name => $field) {
/* #var $field FormField */
$value = new NamedFormValue($data, $name);
$field->setValue($value);
$valid = $field->isValid();
$valid || ($this->invalidFields[$name] = $field);
}
return 0 === count($this->invalidFields);
}
/**
* #return FormField[]
*/
public function getInvalidFields()
{
return $this->invalidFields;
}
}
// defining the form in array notation:
$form = array(
'fields' => array(
'email' => array(
'validator' => 'Email',
'error_msg' => 'Cannot validate emailadress',
),
),
);
// processing the form validation
$messages = array();
$fields = new FormFields($form['fields'], new FormFieldFactory());
$fields->validateOn($_POST)
foreach ($fields->getInvalidFields() as $field) {
$messages[] = $field->getErrorMessage();
}
var_dump($messages);
Exemplary output:
array(1) {
[0]=>
string(27) "Cannot validate emailadress"
}
Try this instead :
public function check()
{
foreach ($this->arraykeys as $i => $value)
{
switch ($value)
{
case 'email' :
$checkmail = new checkEmail($_POST);
$checkmail->chkEmail($_POST['email']);
if ($checkmail->chkEmail($_POST['email']) == false)
{
$this->message[] = 'Cannot validate emailadres';
}
break;
}
}
print_r($this->message);
}
Also be sure your property is set to public.
Are you sure $checkmail->chkEmail() is getting false and is working well ?

PHP RecursiveIterator traversing

I have a structure representing a form and I want to iterate it using RecursiveIterator.
The problem is this only returns the top-level questions. What am I doing wrong?
Whole form:
class Form implements RecursiveIterator{
private $id;
private $caption;
private $other_text;
private $questions = array();
private $current;
private function __construct(DibiRow $row){
$this->id = $row->id;
$this->caption = $row->caption;
$this->other_text = $row->other_text;
$this->loadQuestions();
}
private function loadQuestions(){
$questions = dibi::query('SELECT * FROM cyp_questions WHERE form_id = %i AND parent_id IS NULL', $this->id);
while($question = $questions->fetch()) $this->questions[] = new Question($question->question_id, $question->type, $question->caption, $question->other_text, $question->triggers_unique == 1);
}
/**
* #throws InvalidArgumentException
* #param $id
* #return Form
*/
public static function loadById($id){
$form = dibi::query('SELECT * FROM cyp_forms WHERE id = %i', $id)->fetch();
if($form === false) throw new InvalidArgumentException('Form with id '.$id.' was not found.');
return new Form($form);
}
/**
* #throws FormFieldException
* #return bool
*/
public function validate($postfields){
}
public function getQuestions(){
return $this->questions;
}
public function getChildren(){
return $this->questions[$this->current];
}
public function hasChildren(){
return count($this->questions) > 0;
}
public function current(){
return $this->questions[$this->current];
}
public function key(){
return $this->current;
}
public function next(){
$this->current++;
}
public function rewind(){
$this->current = 0;
}
public function valid(){
return isset($this->questions[$this->current]);
}
}
Question:
class Question implements RecursiveIterator{
private $id;
private $type;
private $answers = array();
private $subquestions = array();
private $other_text;
private $triggers_unique;
private $caption;
private $current = 0;
public function __construct($id, $type, $caption, $other_text = null, $triggers_unique = false){
$this->id = $id;
$this->type = $type;
$this->caption = $caption;
$this->other_text = $other_text;
$this->triggers_unique = $triggers_unique;
$this->setSubQuestions();
}
private function setSubQuestions(){
$questions = dibi::query('SELECT * FROM cyp_questions WHERE parent_id = %i', $this->id);
while($question = $questions->fetch()) $this->subquestions[] = new Question($question->question_id, $question->type, $question->caption, $question->other_text, $question->triggers_unique == 1);
}
public function getOtherText(){
return $this->other_text;
}
public function getCaption(){
return $this->caption;
}
public function addAnswer($answer){
$this->answers[] = $answer;
}
public function getChildren(){
return $this->subquestions[$this->current];
}
public function hasChildren(){
return count($this->subquestions) > 0;
}
public function current(){
return $this->subquestions[$this->current];
}
public function key(){
return $this->id;
}
public function next(){
++$this->current;
}
public function rewind(){
$this->current = 0;
}
public function valid(){
return isset($this->subquestions[$this->current]);
}
public function getAnswers(){
return $this->answers;
}
}
Iteration:
$form = Form::loadById(1);
foreach($form as $question){
echo $question->getCaption().'<br />';
}
To iterate over a RecursiveIterator, you have to wrap it into a RecursiveIteratorIterator.
See some examples at
Introduction to Spl
SplWiki
The default iteration mode is only to list leaves. If you also want the containing nodes to appear in the iteration, pass RecursiveIteratorIterator::SELF_FIRST as the second argument to the constructor of the RecursiveIteratorIterator
Well, as you can see here
public RecursiveIterator RecursiveIterator::getChildren ( void )
Returns an iterator for the current iterator entry.
the method should return an object implementing the iterator. Your method return a simple array.
My guess would be to return something like:
public function getChildren(){
return new Question($this->subquestions);
}
This is because you're using a RECURSIVE iterator so it's expected to have each node of the tree of the same type (an iterator)

Categories