Page MenuHomePhorge

DiagramVersion.php
No OneTemporary

DiagramVersion.php

<?php
final class DiagramVersion extends DiagramDAO implements
PhabricatorDestructibleInterface,
PhabricatorPolicyInterface {
/**
* List of properties mapped to database table columns
*/
protected $phid;
protected $diagramID;
protected $version;
protected $authorPHID;
protected $byteSize;
protected $data;
protected $viewPolicy;
protected $editPolicy;
/**
* returns base64 of $data
*/
public function getBase64Data() {
if ($this->data === null) {
return null;
}
return base64_encode($this->data);
}
/**
* returns the URL which links to the diagram PNG data
*/
public function getDataURI() {
return PhabricatorEnv::getCDNURI(
'/diagram/data/'
.$this->getPHID());
}
/**
* Return an array of capabilities that this object type supports.
* See PhabricatorPolicyCapability for a list of available capabilities.
*
* Interface: PhabricatorPolicyInterface
*/
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
/**
* Return the policy for the given capability.
*
* Interface: PhabricatorPolicyInterface
*/
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return $this->viewPolicy;
case PhabricatorPolicyCapability::CAN_EDIT:
return $this->editPolicy;
default:
return PhabricatorPolicies::POLICY_NOONE;
}
}
/**
* Return the URL which links to the diagram PNG image
*/
public function getViewURI() {
if (!$this->getPHID()) {
throw new Exception(
pht('You must save a diagram before you can generate a view URI.')
);
}
$uri = '/diagram/data/'
.$this->getPHID();
return $uri;
}
/**
* Configures application-wide storage settings.
* This creates a mapping of the corresponding database table.
*/
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_COLUMN_SCHEMA => array(
'diagramID' => 'uint32',
'version' => 'uint32',
'authorPHID' => 'phid',
'byteSize' => 'uint64',
'data' => 'bytes',
'viewPolicy' => 'policy',
'editPolicy' => 'policy',
),
self::CONFIG_KEY_SCHEMA => array(
'key_phid' => null,
'key_diagramID_version' => array(
'columns' => array('diagramID', 'version'),
'unique' => true,
),
'key_authorPHID' => array(
'columns' => array('authorPHID'),
),
),
) +
array(
self::CONFIG_IDS => self::IDS_AUTOINCREMENT,
self::CONFIG_TIMESTAMPS => true,
);
}
/**
* Return the name of the database table that is represented by this class
*/
public function getTableName() {
return 'diagram_version';
}
/**
* Return a string that uniquely identifies the PHID type for this object
* type. This is used by the PHID system to generate and manage PHIDs for
* this object type.
*/
public function getPHIDType() {
return 'DGVN';
}
/**
* Return true if the given user has the given capability automatically,
* without needing to check the object's policy. For example, you might
* return true here if the user is an administrator or if they own the
* object.
*
* Interface: PhabricatorPolicyInterface
*/
public function hasAutomaticCapability(
$capability,
PhabricatorUser $viewer) {
return false;
}
/**
* Creates and initializes a new DiagramVersion object
*/
public static function initializeNewDiagram(PhabricatorUser $actor) {
return id(new self())
->setViewPolicy(PhabricatorPolicies::getMostOpenPolicy())
->setEditPolicy($actor->getPHID())
->setAuthorPHID($actor->getPHID())
->setVersion(1)
->setDateCreated(time())
->setDateModified(time());
}
/**
* Creates a new DiagramVersion object and loads the given base64 data in it
*/
public static function newFromFileData(
$base64_data,
array $params = array()) {
$actor = idx($params, 'actor');
if (!$actor) {
throw new Exception(pht('Missing required actor for new file data.'));
}
$diagramID = idx($params, 'diagramID');
if (!is_numeric($diagramID)) {
$diagramID = null;
}
$data = base64_decode($base64_data);
$diagram = self::initializeNewDiagram($actor);
$diagram->setByteSize(strlen($data));
$diagram->setData($data);
$diagram->setDiagramID($diagramID);
$diagram->save();
return $diagram;
}
/**
* Permanently destroy this object. This is used by the destructible
* interface to allow administrators to permanently delete objects from
* the system.
*/
public function destroyObjectPermanently(
PhabricatorDestructionEngine $engine) {
$this->openTransaction();
$this->delete();
$this->saveTransaction();
}
/**
* Returns an ID which can be used for a newly created Diagram object
*/
public function generateDiagramID() {
$conn_r = $this->establishConnection('r');
$table_name = $this->getTableName();
$max_diagram_id = queryfx_one(
$conn_r,
'SELECT MAX(diagramID) max_diagram_id FROM %T',
$table_name)['max_diagram_id'];
return (int)$max_diagram_id + 1;
}
/**
* Returns all DiagramVersion objects for a given diagram
*/
public function loadByDiagramID($diagramID) {
if (is_object($diagramID)) {
$diagramID = (string)$diagramID;
}
if (!$diagramID || (!is_int($diagramID) && !ctype_digit($diagramID))) {
return null;
}
return $this->loadAllWhere(
'diagramID = %d ORDER BY version DESC',
$diagramID);
}
/**
* Returns the latest version of the given diagram
*/
public function loadLatestByDiagramID($diagramID) {
if (is_object($diagramID)) {
$diagramID = (string)$diagramID;
}
if (!$diagramID || (!is_int($diagramID) && !ctype_digit($diagramID))) {
return null;
}
return $this->loadOneWhere(
'diagramID = %d ORDER BY version DESC LIMIT 1',
$diagramID);
}
/**
* Returns a specific DiagramVersion object
*/
public function loadByDiagramPHID($diagramVersionPHID) {
if (is_object($diagramVersionPHID)) {
$diagramVersionPHID = (string)$diagramVersionPHID;
}
return $this->loadOneWhere(
'phid = %s ORDER BY version DESC LIMIT 1',
$diagramVersionPHID);
}
/**
* Returns a specific DiagramVersion object for a given diagram and
* version number
*/
public function loadByVersionedDiagramID($diagramID, $version) {
if (is_object($diagramID)) {
$diagramID = (string)$diagramID;
}
if (is_object($version)) {
$version = (string)$version;
}
if (!$diagramID || (!is_int($diagramID) && !ctype_digit($diagramID))) {
return null;
}
if (!$version || (!is_int($version) && !ctype_digit($version))) {
return null;
}
return $this->loadOneWhere(
'diagramID = %d AND version = %d',
$diagramID,
$version);
}
/**
* Publishes a modification of a diagram via email
*/
public function publishNewVersion($request, $diagram_id) {
$xactions[] = id(new DiagramTransaction())
->setTransactionType(DiagramContentTransaction::TRANSACTIONTYPE)
->setNewValue(array('=' => $diagram_id));
if ($request instanceof ConduitAPIRequest) {
// Handle ConduitAPIRequest
$viewer = $request->getUser();
// Set the content source for the transaction editor
$content_source = PhabricatorContentSource::newForSource(
PhabricatorConduitContentSource::SOURCECONST,
array(
'params' => $request->getAllParameters()
));
$editor = id(new DiagramTransactionEditor())
->setActor($viewer)
->setContentSource($content_source)
->setContinueOnNoEffect(true);
} elseif ($request instanceof AphrontRequest) {
// Handle AphrontRequest
$viewer = $request->getViewer();
$editor = id(new DiagramTransactionEditor())
->setActor($viewer)
->setContentSourceFromRequest($request)
->setContinueOnNoEffect(true);
} else {
// Handle other types of requests
throw new Exception('Unsupported request type');
}
$diagram = id(new Diagram())->loadByID($diagram_id);
$editor->applyTransactions($diagram, $xactions);
}
/**
* Stores a new diagram (version)
*/
public function save() {
// Load the last record with the same PHID.
$last_record = null;
if ($this->getDiagramID() !== null) {
$last_record = id(new PhabricatorDiagramVersionQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withDiagramIDs(array($this->getDiagramID()))
->setLimit(1)
->executeOne();
}
if ($last_record === null) {
// If there is no last record, this is a new diagram object.
$this->setVersion(1);
$newDiagram = new Diagram();
$newDiagram->createNewDiagram();
$this->setDiagramID($newDiagram->getID());
} else {
// If there is a last record, this is a new version of an existing
// diagram object.
$this->setVersion($last_record->getVersion() + 1);
$this->setDateCreated($last_record->getDateCreated());
}
// Check if a row with the same PHID and version already exists
$existing_record = null;
if ($this->getPHID() !== null && $this->getVersion() !== null) {
$existing_record = id(new PhabricatorDiagramVersionQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withPHIDs(array($this->getPHID()))
->withWhere(
array(
array('version', '=', $this->getVersion()),
))
->setLimit(1)
->executeOne();
}
if ($existing_record === null) {
// If there is no existing record, create a new row in the table.
$conn_w = $this->establishConnection('w');
$table_name = $this->getTableName();
$this->phid = $this->generatePHID();
if ($this->diagramID === null) {
$this->diagramID = $this->generateDiagramID();
}
$record = array(
'phid' => $this->getPHID(),
'diagramID' => $this->getDiagramID(),
'version' => $this->getVersion(),
'authorPHID' => $this->getAuthorPHID(),
'dateCreated' => $this->getDateCreated(),
'dateModified' => $this->getDateModified(),
'byteSize' => $this->getByteSize(),
'viewPolicy' => $this->getViewPolicy(),
'editPolicy' => $this->getEditPolicy(),
'data' => $this->getData(),
);
if ($this->getID() !== null) {
// If the ID property is set, include it in the data to insert.
$record['id'] = $this->getID();
}
queryfx(
$conn_w,
'INSERT INTO %T (%Q) VALUES (%Ls, %B)',
$table_name,
implode(', ', array_keys($record)),
array_values(array_slice($record, 0, -1)),
end($record));
$this->id = $conn_w->getInsertID();
} else {
// If there is an existing record, throw an exception.
throw new Exception(
pht('A diagram with PHID "%s" and version "%s" already exists.',
$this->getPHID(),
$this->getVersion())
);
}
return $this;
}
}

File Metadata

Mime Type
text/x-php
Expires
Sun, Jan 19, 19:56 (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1116194
Default Alt Text
DiagramVersion.php (11 KB)

Event Timeline