<?php
/*
* SCROTT IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* For more information, please refer to UNLICENSE
*/
require_once "class/object.class.php";
require_once "class/pad.class.php";
require_once "class/issue.class.php";
/*
* This class models Scrott pad stages. Stages form a pipeline through
* which issues can progress.
*/
class stage extends object
{
/*
* Constructor
*/
public function __construct(?string $guid = NULL)
{
$this->fields['stages'] = array(
"guid",
"stage",
);
parent::__construct($guid);
$this->expectType("stage");
}
/*
* Initialize a new stage object with the given name and parent
* pad.
*/
public static function initNew(string $name, pad $parent) : stage
{
$stage = new stage();
$stage->setParent($parent);
$stage->name = $name;
$stage->objtype = "stage";
return $stage;
}
/*
* Get the stage following this one in the pipeline. NULL is
* returned if no stage is next.
*/
public function getNext() : ?stage
{
if (!isset($this->stage) || $this->stage == "")
return NULL;
return new stage($this->stage);
}
/*
* Get the stage preceding this one in the pipeline. NULL is
* returned if no stage is previous.
*/
public function getPrev() : ?stage
{
$pad = $this->getParent();
if ($pad->stage == $this->guid)
return NULL;
$query = "SELECT guid FROM stages WHERE stage = '" . database::esc($this->guid) . "'";
$res = database::query($query);
if (count($res) == 0)
return NULL;
return new stage($res[0]['guid']);
}
/*
* Get an array of all stages reachable from this one. The array
* is in proper order and includes the current stage.
*/
public function getArray() : array
{
$stages = array();
$curr = $this;
do $stages[] = $curr;
while (($curr = $curr->getNext()));
return $stages;
}
/*
* Get all issues in this stage, sorted by due date, then by
* issue number.
*/
public function getIssues_ordByDueByNumb() : array
{
$query = "SELECT o.guid FROM objects o JOIN issues i ON o.guid = i.guid " .
"WHERE o.objtype = 'issue' AND o.parent = '" . database::esc($this->guid) .
"' ORDER BY i.due, i.numb";
$res = database::query($query);
$issues = array();
foreach ($res as $i)
$issues[] = new issue($i['guid']);
return $issues;
}
/*
* Reorder the stages of a pipeline by moving this one forward.
* This swaps the places of the current stage and the one following
* it. If this stage is the last in its pipeline, nothing is done
* and false is returned.
*/
public function moveForward() : bool
{
if (!($next = $this->getNext()))
return false;
if (!($prev = $this->getPrev()))
$prev = $this->getParent();
$tmp = $next->stage;
$prev->stage = $next->guid;
$next->stage = $this->guid;
$this->stage = $tmp;
$next->saveObj();
$prev->saveObj();
$this->saveObj();
return true;
}
/*
* Reorder the stages of a pipeline by moving this one backward.
* This swaps the places of the current stage and the one preceding
* it. If this stage is the first in its pipeline, nothing is done
* and false is returned.
*/
public function moveBackward() : bool
{
if (!($prev = $this->getPrev()))
return false;
return $prev->moveForward();
}
/*
* Insert a stage object in this pipeline, following $this object
*/
public function insertStage(stage $stage) : void
{
$stage->stage = $this->stage;
$this->stage = $stage->guid;
$stage->saveObj();
$this->saveObj();
}
/*
* Remove this stage object and move all of its issues. Issues are
* moved to the given stage object. Additionally, the pad may be
* given, in which case, those issues will be closed.
*/
public function removeStage(object $mvt) : void
{
if (!($prev = $this->getPrev()))
$prev = $this->getParent();
foreach ($this->getIssues_ordByDueByNumb() as $i)
$i->setParent($mvt);
$prev->stage = $this->stage;
$prev->saveObj();
$this->delObj();
}
}
?>