This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,50 @@
<?php
namespace Gedmo\IpTraceable;
/**
* This interface is not necessary but can be implemented for
* Entities which in some cases needs to be identified as
* IpTraceable
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
interface IpTraceable
{
// ipTraceable expects annotations on properties
/**
* @gedmo:IpTraceable(on="create")
* strings which should be updated on insert only
*/
/**
* @gedmo:IpTraceable(on="update")
* strings which should be updated on update and insert
*/
/**
* @gedmo:IpTraceable(on="change", field="field", value="value")
* strings which should be updated on changed "property"
* value and become equal to given "value"
*/
/**
* @gedmo:IpTraceable(on="change", field="field")
* strings which should be updated on changed "property"
*/
/**
* @gedmo:IpTraceable(on="change", fields={"field1", "field2"})
* strings which should be updated if at least one of the given fields changed
*/
/**
* example
*
* @gedmo:IpTraceable(on="create")
* @Column(type="string")
* $created
*/
}

View File

@@ -0,0 +1,59 @@
<?php
namespace Gedmo\IpTraceable;
use Gedmo\AbstractTrackingListener;
use Gedmo\Exception\InvalidArgumentException;
use Gedmo\Mapping\Event\AdapterInterface;
/**
* The IpTraceable listener handles the update of
* IPs on creation and update.
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class IpTraceableListener extends AbstractTrackingListener
{
/**
* @var string|null
*/
protected $ip;
/**
* Get the ipValue value to set on a ip field
*
* @param object $meta
* @param string $field
* @param AdapterInterface $eventAdapter
*
* @return null|string
*/
public function getFieldValue($meta, $field, $eventAdapter)
{
return $this->ip;
}
/**
* Set a ip value to return
*
* @param string $ip
* @throws InvalidArgumentException
*/
public function setIpValue($ip = null)
{
if (isset($ip) && filter_var($ip, FILTER_VALIDATE_IP) === false) {
throw new InvalidArgumentException("ip address is not valid $ip");
}
$this->ip = $ip;
}
/**
* {@inheritDoc}
*/
protected function getNamespace()
{
return __NAMESPACE__;
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Gedmo\IpTraceable\Mapping\Driver;
use Gedmo\Mapping\Driver\AbstractAnnotationDriver;
use Gedmo\Exception\InvalidMappingException;
/**
* This is an annotation mapping driver for IpTraceable
* behavioral extension. Used for extraction of extended
* metadata from Annotations specifically for IpTraceable
* extension.
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Annotation extends AbstractAnnotationDriver
{
/**
* Annotation field is ipTraceable
*/
const IP_TRACEABLE = 'Gedmo\\Mapping\\Annotation\\IpTraceable';
/**
* List of types which are valid for IP
*
* @var array
*/
protected $validTypes = array(
'string',
);
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
$class = $this->getMetaReflectionClass($meta);
// property annotations
foreach ($class->getProperties() as $property) {
if ($meta->isMappedSuperclass && !$property->isPrivate() ||
$meta->isInheritedField($property->name) ||
isset($meta->associationMappings[$property->name]['inherited'])
) {
continue;
}
if ($ipTraceable = $this->reader->getPropertyAnnotation($property, self::IP_TRACEABLE)) {
$field = $property->getName();
if (!$meta->hasField($field)) {
throw new InvalidMappingException("Unable to find ipTraceable [{$field}] as mapped property in entity - {$meta->name}");
}
if ($meta->hasField($field) && !$this->isValidField($meta, $field)) {
throw new InvalidMappingException("Field - [{$field}] type is not valid and must be 'string' - {$meta->name}");
}
if (!in_array($ipTraceable->on, array('update', 'create', 'change'))) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->name}");
}
if ($ipTraceable->on == 'change') {
if (!isset($ipTraceable->field)) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->name}");
}
if (is_array($ipTraceable->field) && isset($ipTraceable->value)) {
throw new InvalidMappingException("IpTraceable extension does not support multiple value changeset detection yet.");
}
$field = array(
'field' => $field,
'trackedField' => $ipTraceable->field,
'value' => $ipTraceable->value,
);
}
// properties are unique and mapper checks that, no risk here
$config[$ipTraceable->on][] = $field;
}
}
}
}

View File

@@ -0,0 +1,133 @@
<?php
namespace Gedmo\IpTraceable\Mapping\Driver;
use Gedmo\Mapping\Driver\Xml as BaseXml;
use Gedmo\Exception\InvalidMappingException;
/**
* This is a xml mapping driver for IpTraceable
* behavioral extension. Used for extraction of extended
* metadata from xml specifically for IpTraceable
* extension.
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @author Miha Vrhovnik <miha.vrhovnik@gmail.com>
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Xml extends BaseXml
{
/**
* List of types which are valid for IP
*
* @var array
*/
private $validTypes = array(
'string',
);
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
/**
* @var \SimpleXmlElement $mapping
*/
$mapping = $this->_getMapping($meta->name);
if (isset($mapping->field)) {
/**
* @var \SimpleXmlElement $fieldMapping
*/
foreach ($mapping->field as $fieldMapping) {
$fieldMappingDoctrine = $fieldMapping;
$fieldMapping = $fieldMapping->children(self::GEDMO_NAMESPACE_URI);
if (isset($fieldMapping->{'ip-traceable'})) {
/**
* @var \SimpleXmlElement $data
*/
$data = $fieldMapping->{'ip-traceable'};
$field = $this->_getAttribute($fieldMappingDoctrine, 'name');
if (!$this->isValidField($meta, $field)) {
throw new InvalidMappingException("Field - [{$field}] type is not valid and must be 'string' in class - {$meta->name}");
}
if (!$this->_isAttributeSet($data, 'on') || !in_array($this->_getAttribute($data, 'on'), array('update', 'create', 'change'))) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->name}");
}
if ($this->_getAttribute($data, 'on') == 'change') {
if (!$this->_isAttributeSet($data, 'field')) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->name}");
}
$trackedFieldAttribute = $this->_getAttribute($data, 'field');
$valueAttribute = $this->_isAttributeSet($data, 'value') ? $this->_getAttribute($data, 'value' ) : null;
if (is_array($trackedFieldAttribute) && null !== $valueAttribute) {
throw new InvalidMappingException("IpTraceable extension does not support multiple value changeset detection yet.");
}
$field = array(
'field' => $field,
'trackedField' => $trackedFieldAttribute,
'value' => $valueAttribute,
);
}
$config[$this->_getAttribute($data, 'on')][] = $field;
}
}
}
if (isset($mapping->{'many-to-one'})) {
foreach ($mapping->{'many-to-one'} as $fieldMapping) {
$field = $this->_getAttribute($fieldMapping, 'field');
$fieldMapping = $fieldMapping->children(self::GEDMO_NAMESPACE_URI);
if (isset($fieldMapping->{'ip-traceable'})) {
/**
* @var \SimpleXmlElement $data
*/
$data = $fieldMapping->{'ip-traceable'};
if (! $meta->isSingleValuedAssociation($field)) {
throw new InvalidMappingException("Association - [{$field}] is not valid, it must be a one-to-many relation or a string field - {$meta->name}");
}
if (!$this->_isAttributeSet($data, 'on') || !in_array($this->_getAttribute($data, 'on'), array('update', 'create', 'change'))) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->name}");
}
if ($this->_getAttribute($data, 'on') == 'change') {
if (!$this->_isAttributeSet($data, 'field')) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->name}");
}
$trackedFieldAttribute = $this->_getAttribute($data, 'field');
$valueAttribute = $this->_isAttributeSet($data, 'value') ? $this->_getAttribute($data, 'value' ) : null;
if (is_array($trackedFieldAttribute) && null !== $valueAttribute) {
throw new InvalidMappingException("IpTraceable extension does not support multiple value changeset detection yet.");
}
$field = array(
'field' => $field,
'trackedField' => $trackedFieldAttribute,
'value' => $valueAttribute,
);
}
$config[$this->_getAttribute($data, 'on')][] = $field;
}
}
}
}
/**
* Checks if $field type is valid
*
* @param object $meta
* @param string $field
*
* @return boolean
*/
protected function isValidField($meta, $field)
{
$mapping = $meta->getFieldMapping($field);
return $mapping && in_array($mapping['type'], $this->validTypes);
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace Gedmo\IpTraceable\Mapping\Driver;
use Gedmo\Mapping\Driver\File;
use Gedmo\Mapping\Driver;
use Gedmo\Exception\InvalidMappingException;
/**
* This is a yaml mapping driver for IpTraceable
* behavioral extension. Used for extraction of extended
* metadata from yaml specifically for IpTraceable
* extension.
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class Yaml extends File implements Driver
{
/**
* File extension
* @var string
*/
protected $_extension = '.dcm.yml';
/**
* List of types which are valid for IP
*
* @var array
*/
private $validTypes = array(
'string',
);
/**
* {@inheritDoc}
*/
public function readExtendedMetadata($meta, array &$config)
{
$mapping = $this->_getMapping($meta->name);
if (isset($mapping['fields'])) {
foreach ($mapping['fields'] as $field => $fieldMapping) {
if (isset($fieldMapping['gedmo']['ipTraceable'])) {
$mappingProperty = $fieldMapping['gedmo']['ipTraceable'];
if (!$this->isValidField($meta, $field)) {
throw new InvalidMappingException("Field - [{$field}] type is not valid and must be 'string' in class - {$meta->name}");
}
if (!isset($mappingProperty['on']) || !in_array($mappingProperty['on'], array('update', 'create', 'change'))) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->name}");
}
if ($mappingProperty['on'] == 'change') {
if (!isset($mappingProperty['field'])) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->name}");
}
$trackedFieldAttribute = $mappingProperty['field'];
$valueAttribute = isset($mappingProperty['value']) ? $mappingProperty['value'] : null;
if (is_array($trackedFieldAttribute) && null !== $valueAttribute) {
throw new InvalidMappingException("IpTraceable extension does not support multiple value changeset detection yet.");
}
$field = array(
'field' => $field,
'trackedField' => $trackedFieldAttribute,
'value' => $valueAttribute,
);
}
$config[$mappingProperty['on']][] = $field;
}
}
}
if (isset($mapping['manyToOne'])) {
foreach ($mapping['manyToOne'] as $field => $fieldMapping) {
if (isset($fieldMapping['gedmo']['ipTraceable'])) {
$mappingProperty = $fieldMapping['gedmo']['ipTraceable'];
if (! $meta->isSingleValuedAssociation($field)) {
throw new InvalidMappingException("Association - [{$field}] is not valid, it must be a one-to-many relation or a string field - {$meta->name}");
}
if (!isset($mappingProperty['on']) || !in_array($mappingProperty['on'], array('update', 'create', 'change'))) {
throw new InvalidMappingException("Field - [{$field}] trigger 'on' is not one of [update, create, change] in class - {$meta->name}");
}
if ($mappingProperty['on'] == 'change') {
if (!isset($mappingProperty['field'])) {
throw new InvalidMappingException("Missing parameters on property - {$field}, field must be set on [change] trigger in class - {$meta->name}");
}
$trackedFieldAttribute = $mappingProperty['field'];
$valueAttribute = isset($mappingProperty['value']) ? $mappingProperty['value'] : null;
if (is_array($trackedFieldAttribute) && null !== $valueAttribute) {
throw new InvalidMappingException("IpTraceable extension does not support multiple value changeset detection yet.");
}
$field = array(
'field' => $field,
'trackedField' => $trackedFieldAttribute,
'value' => $valueAttribute,
);
}
$config[$mappingProperty['on']][] = $field;
}
}
}
}
/**
* {@inheritDoc}
*/
protected function _loadMappingFile($file)
{
return \Symfony\Component\Yaml\Yaml::parse(file_get_contents($file));
}
/**
* Checks if $field type is valid
*
* @param object $meta
* @param string $field
*
* @return boolean
*/
protected function isValidField($meta, $field)
{
$mapping = $meta->getFieldMapping($field);
return $mapping && in_array($mapping['type'], $this->validTypes);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Gedmo\IpTraceable\Mapping\Event\Adapter;
use Gedmo\Mapping\Event\Adapter\ODM as BaseAdapterODM;
use Gedmo\IpTraceable\Mapping\Event\IpTraceableAdapter;
/**
* Doctrine event adapter for ODM adapted
* for IpTraceable behavior
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
final class ODM extends BaseAdapterODM implements IpTraceableAdapter
{
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Gedmo\IpTraceable\Mapping\Event\Adapter;
use Gedmo\Mapping\Event\Adapter\ORM as BaseAdapterORM;
use Gedmo\IpTraceable\Mapping\Event\IpTraceableAdapter;
/**
* Doctrine event adapter for ORM adapted
* for IpTraceable behavior
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
final class ORM extends BaseAdapterORM implements IpTraceableAdapter
{
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Gedmo\IpTraceable\Mapping\Event;
use Gedmo\Mapping\Event\AdapterInterface;
/**
* Doctrine event adapter interface
* for IpTraceable behavior
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
interface IpTraceableAdapter extends AdapterInterface
{
}

View File

@@ -0,0 +1,68 @@
<?php
namespace Gedmo\IpTraceable\Traits;
/**
* IpTraceable Trait, usable with PHP >= 5.4
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
trait IpTraceable
{
/**
* @var string
*/
protected $createdFromIp;
/**
* @var string
*/
protected $updatedFromIp;
/**
* Sets createdFromIp.
*
* @param string $createdFromIp
* @return $this
*/
public function setCreatedFromIp($createdFromIp)
{
$this->createdFromIp = $createdFromIp;
return $this;
}
/**
* Returns createdFromIp.
*
* @return string
*/
public function getCreatedFromIp()
{
return $this->createdFromIp;
}
/**
* Sets updatedFromIp.
*
* @param string $updatedFromIp
* @return $this
*/
public function setUpdatedFromIp($updatedFromIp)
{
$this->updatedFromIp = $updatedFromIp;
return $this;
}
/**
* Returns updatedFromIp.
*
* @return string
*/
public function getUpdatedFromIp()
{
return $this->updatedFromIp;
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Gedmo\IpTraceable\Traits;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* IpTraceable Trait, usable with PHP >= 5.4
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
trait IpTraceableDocument
{
/**
* @var string
* @Gedmo\IpTraceable(on="create")
* @ODM\Field(type="string")
*/
protected $createdFromIp;
/**
* @var string
* @Gedmo\IpTraceable(on="update")
* @ODM\Field(type="string")
*/
protected $updatedFromIp;
/**
* Sets createdFromIp.
*
* @param string $createdFromIp
* @return $this
*/
public function setCreatedFromIp($createdFromIp)
{
$this->createdFromIp = $createdFromIp;
return $this;
}
/**
* Returns createdFromIp.
*
* @return string
*/
public function getCreatedFromIp()
{
return $this->createdFromIp;
}
/**
* Sets updatedFromIp.
*
* @param string $updatedFromIp
* @return $this
*/
public function setUpdatedFromIp($updatedFromIp)
{
$this->updatedFromIp = $updatedFromIp;
return $this;
}
/**
* Returns updatedFromIp.
*
* @return string
*/
public function getUpdatedFromIp()
{
return $this->updatedFromIp;
}
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Gedmo\IpTraceable\Traits;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* IpTraceable Trait, usable with PHP >= 5.4
*
* @author Pierre-Charles Bertineau <pc.bertineau@alterphp.com>
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
trait IpTraceableEntity
{
/**
* @var string
* @Gedmo\IpTraceable(on="create")
* @ORM\Column(length=45, nullable=true)
*/
protected $createdFromIp;
/**
* @var string
* @Gedmo\IpTraceable(on="update")
* @ORM\Column(length=45, nullable=true)
*/
protected $updatedFromIp;
/**
* Sets createdFromIp.
*
* @param string $createdFromIp
* @return $this
*/
public function setCreatedFromIp($createdFromIp)
{
$this->createdFromIp = $createdFromIp;
return $this;
}
/**
* Returns createdFromIp.
*
* @return string
*/
public function getCreatedFromIp()
{
return $this->createdFromIp;
}
/**
* Sets updatedFromIp.
*
* @param string $updatedFromIp
* @return $this
*/
public function setUpdatedFromIp($updatedFromIp)
{
$this->updatedFromIp = $updatedFromIp;
return $this;
}
/**
* Returns updatedFromIp.
*
* @return string
*/
public function getUpdatedFromIp()
{
return $this->updatedFromIp;
}
}