diff --git a/appinfo/info.xml b/appinfo/info.xml index bc54a69..4e92bec 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Custom Properties Files app plugin to add custom properties to files and folders Files app plugin to add custom properties to files and folders - 1.0.0 + 1.0.1 agpl SteKoe CustomProperties diff --git a/build.sh b/build.sh index 0eb161a..6fc40d8 100755 --- a/build.sh +++ b/build.sh @@ -38,12 +38,11 @@ signSource() { rm -rf customproperties/.git customproperties/src - cid=$(docker run -d -v `pwd`/customproperties:/app -v ~/.nextcloud/certificates/:/nextcloud/certificates/ nextcloud) + cid=$(docker run -d -v $(pwd)/customproperties:/app -v ~/.nextcloud/certificates/:/nextcloud/certificates/ nextcloud) echo "Sign sources using container '$cid'..." echo "Waiting for NextCloud to be initialized..." - until docker logs $cid 2>&1 | grep "Initializing finished" > /dev/null; - do + until docker logs $cid 2>&1 | grep "Initializing finished" >/dev/null; do sleep 1 echo "Waiting..." done @@ -53,16 +52,16 @@ signSource() { docker exec -i $cid /bin/bash -c "chmod -R +w /app" || true docker exec -i $cid php occ integrity:sign-app --privateKey=/nextcloud/certificates/customproperties.key --certificate=/nextcloud/certificates/customproperties.crt --path=/app || true echo "Tidy up..." - docker rm -f $cid > /dev/null + docker rm -f $cid >/dev/null } buildArchive() { echo "Build archive..." (tar -czf customproperties.tar.gz \ - --exclude=./src/node_modules/ \ - --exclude=./.git/ \ - --exclude=./src/ \ - customproperties/) + --exclude=./src/node_modules/ \ + --exclude=./.git/ \ + --exclude=./src/ \ + customproperties/) } createSignature() { diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 4eb9985..1fa49eb 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -3,28 +3,30 @@ namespace OCA\CustomProperties\AppInfo; use OCP\AppFramework\App; -use OCP\EventDispatcher\IEventDispatcher; +use OCP\AppFramework\QueryException; use OCP\Util; -class Application extends App { - const APP_NAME = 'customproperties'; +class Application extends App +{ + const APP_NAME = 'customproperties'; - /** - * Application constructor. - * - * @param array $params - * @throws \OCP\AppFramework\QueryException - */ - public function __construct(array $params = []) { - parent::__construct(self::APP_NAME, $params); + /** + * Application constructor. + * + * @param array $params + * @throws QueryException + */ + public function __construct(array $params = []) + { + parent::__construct(self::APP_NAME, $params); - $container = $this->getContainer(); - $server = $container->getServer(); - $eventDispatcher = $server->getEventDispatcher(); + $container = $this->getContainer(); + $server = $container->getServer(); + $eventDispatcher = $server->getEventDispatcher(); - $eventDispatcher->addListener('OCA\Files::loadAdditionalScripts', function () { - Util::addStyle('customproperties', 'sidebartab'); - Util::addScript('customproperties', 'sidebartab'); - }); - } + $eventDispatcher->addListener('OCA\Files::loadAdditionalScripts', function () { + Util::addStyle('customproperties', 'sidebartab'); + Util::addScript('customproperties', 'sidebartab'); + }); + } } diff --git a/lib/Controller/AdminSettingsController.php b/lib/Controller/AdminSettingsController.php index 0500c03..2f5cae7 100644 --- a/lib/Controller/AdminSettingsController.php +++ b/lib/Controller/AdminSettingsController.php @@ -8,44 +8,52 @@ use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; -class AdminSettingsController extends Controller { - - /** - * @var CustomPropertiesMapper - */ - private $customPropertiesMapper; - - public function __construct($AppName, IRequest $request, CustomPropertiesMapper $customPropertiesMapper) { - parent::__construct($AppName, $request); - $this->customPropertiesMapper = $customPropertiesMapper; - } - - /** - * @return JSONResponse - */ - public function index() :JSONResponse { - $res = $this->customPropertiesMapper->findAll(); - return new JSONResponse($res); - } - - /** - * @param string $propertylabel - * @return CustomProperty - */ - public function create(string $propertylabel) : CustomProperty { - $customProperty = new CustomProperty(); - $customProperty->setPropertylabel($propertylabel); - $customProperty->setPropertyname(CustomProperty::createSlug($propertylabel)); - return $this->customPropertiesMapper->insert($customProperty); - } - - /** - * @param int $id - * @return CustomProperty - */ - public function delete(int $id) : CustomProperty { - $customProperty = $this->customPropertiesMapper->findById($id); - return $this->customPropertiesMapper->delete($customProperty); - } +class AdminSettingsController extends Controller +{ + + /** + * @var CustomPropertiesMapper + */ + private $customPropertiesMapper; + + public function __construct($AppName, IRequest $request, CustomPropertiesMapper $customPropertiesMapper) + { + parent::__construct($AppName, $request); + $this->customPropertiesMapper = $customPropertiesMapper; + } + + /** + * @NoCSRFRequired + * @return JSONResponse + */ + public function index(): JSONResponse + { + $res = $this->customPropertiesMapper->findAll(); + return new JSONResponse($res); + } + + /** + * @NoCSRFRequired + * @param string $propertylabel + * @return CustomProperty + */ + public function create(string $propertylabel): CustomProperty + { + $customProperty = new CustomProperty(); + $customProperty->setPropertylabel($propertylabel); + $customProperty->setPropertyname(CustomProperty::createSlug($propertylabel)); + return $this->customPropertiesMapper->insert($customProperty); + } + + /** + * @NoCSRFRequired + * @param int $id + * @return CustomProperty + */ + public function delete(int $id): CustomProperty + { + $customProperty = $this->customPropertiesMapper->findById($id); + return $this->customPropertiesMapper->delete($customProperty); + } } \ No newline at end of file diff --git a/lib/Controller/CustomPropertiesController.php b/lib/Controller/CustomPropertiesController.php index 2e0bcc3..c151d38 100644 --- a/lib/Controller/CustomPropertiesController.php +++ b/lib/Controller/CustomPropertiesController.php @@ -3,78 +3,80 @@ namespace OCA\CustomProperties\Controller; use Exception; -use OC\Files\Filesystem; use OCA\CustomProperties\Db\CustomPropertiesMapper; use OCA\CustomProperties\Db\PropertiesMapper; use OCA\CustomProperties\Db\Property; use OCA\CustomProperties\Service\PropertyService; use OCP\AppFramework\Controller; -use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Http\JSONResponse; use OCP\ILogger; use OCP\IRequest; -use function Aws\map; -class CustomPropertiesController extends Controller { - const NS_PREFIX = "{http://owncloud.org/ns}"; +class CustomPropertiesController extends Controller +{ + const NS_PREFIX = "{http://owncloud.org/ns}"; - /** - * @var PropertyService - */ - private $propertyService; - /** - * @var CustomPropertiesMapper - */ - private $customPropertiesMapper; - /** - * @var PropertiesMapper - */ - private $propertiesMapper; - /** - * @var ILogger - */ - private $logger; - private $userId; + /** + * @var PropertyService + */ + private $propertyService; + /** + * @var CustomPropertiesMapper + */ + private $customPropertiesMapper; + /** + * @var PropertiesMapper + */ + private $propertiesMapper; + /** + * @var ILogger + */ + private $logger; + private $userId; - public function __construct($AppName, IRequest $request, PropertyService $propertyService, CustomPropertiesMapper $customPropertiesMapper, PropertiesMapper $propertiesMapper, ILogger $logger, $UserId) { - parent::__construct($AppName, $request); - $this->propertyService = $propertyService; - $this->customPropertiesMapper = $customPropertiesMapper; - $this->propertiesMapper = $propertiesMapper; - $this->logger = $logger; - $this->userId = $UserId; - } + public function __construct($AppName, IRequest $request, PropertyService $propertyService, CustomPropertiesMapper $customPropertiesMapper, PropertiesMapper $propertiesMapper, ILogger $logger, $UserId) + { + parent::__construct($AppName, $request); + $this->propertyService = $propertyService; + $this->customPropertiesMapper = $customPropertiesMapper; + $this->propertiesMapper = $propertiesMapper; + $this->logger = $logger; + $this->userId = $UserId; + } - /** - * @NoAdminRequired - * @NoCSRFRequired - * @param string $path - * @param string $name - * @return JSONResponse - */ - public function index(string $path, string $name): JSONResponse { - $res = $this->propertyService->getProperties($this->userId, $path, $name); - return new JSONResponse($res); - } + /** + * @NoAdminRequired + * @NoCSRFRequired + * @param string $path + * @param string $name + * @return JSONResponse + */ + public function index(string $path, string $name): JSONResponse + { + $res = $this->propertyService->getProperties($this->userId, $path, $name); + return new JSONResponse($res); + } - /** - * @NoAdminRequired - */ - public function update(string $propertypath, string $propertyname, string $propertyvalue): Property { - $propertyname = CustomPropertiesController::NS_PREFIX . $propertyname; + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function update(string $propertypath, string $propertyname, string $propertyvalue): Property + { + $propertyname = CustomPropertiesController::NS_PREFIX . $propertyname; - try { - $res = $this->propertiesMapper->findByPathAndName($propertypath, $propertyname, $this->userId); - $res->setPropertyvalue($propertyvalue); - return $this->propertiesMapper->update($res); - } catch (Exception $exception) { - $property = new Property(); - $property->setUserid($this->userId); - $property->setPropertypath($propertypath); - $property->setPropertyname($propertyname); - $property->setPropertyvalue($propertyvalue); + try { + $res = $this->propertiesMapper->findByPathAndName($propertypath, $propertyname, $this->userId); + $res->setPropertyvalue($propertyvalue); + return $this->propertiesMapper->update($res); + } catch (Exception $exception) { + $property = new Property(); + $property->setUserid($this->userId); + $property->setPropertypath($propertypath); + $property->setPropertyname($propertyname); + $property->setPropertyvalue($propertyvalue); - return $this->propertiesMapper->insert($property); - } - } + return $this->propertiesMapper->insert($property); + } + } } diff --git a/lib/Controller/PersonalSettingsController.php b/lib/Controller/PersonalSettingsController.php index 0500c03..c7a6724 100644 --- a/lib/Controller/PersonalSettingsController.php +++ b/lib/Controller/PersonalSettingsController.php @@ -8,44 +8,49 @@ use OCP\AppFramework\Http\JSONResponse; use OCP\IRequest; -class AdminSettingsController extends Controller { - - /** - * @var CustomPropertiesMapper - */ - private $customPropertiesMapper; - - public function __construct($AppName, IRequest $request, CustomPropertiesMapper $customPropertiesMapper) { - parent::__construct($AppName, $request); - $this->customPropertiesMapper = $customPropertiesMapper; - } - - /** - * @return JSONResponse - */ - public function index() :JSONResponse { - $res = $this->customPropertiesMapper->findAll(); - return new JSONResponse($res); - } - - /** - * @param string $propertylabel - * @return CustomProperty - */ - public function create(string $propertylabel) : CustomProperty { - $customProperty = new CustomProperty(); - $customProperty->setPropertylabel($propertylabel); - $customProperty->setPropertyname(CustomProperty::createSlug($propertylabel)); - return $this->customPropertiesMapper->insert($customProperty); - } - - /** - * @param int $id - * @return CustomProperty - */ - public function delete(int $id) : CustomProperty { - $customProperty = $this->customPropertiesMapper->findById($id); - return $this->customPropertiesMapper->delete($customProperty); - } +class AdminSettingsController extends Controller +{ + + /** + * @var CustomPropertiesMapper + */ + private $customPropertiesMapper; + + public function __construct($AppName, IRequest $request, CustomPropertiesMapper $customPropertiesMapper) + { + parent::__construct($AppName, $request); + $this->customPropertiesMapper = $customPropertiesMapper; + } + + /** + * @return JSONResponse + */ + public function index(): JSONResponse + { + $res = $this->customPropertiesMapper->findAll(); + return new JSONResponse($res); + } + + /** + * @param string $propertylabel + * @return CustomProperty + */ + public function create(string $propertylabel): CustomProperty + { + $customProperty = new CustomProperty(); + $customProperty->setPropertylabel($propertylabel); + $customProperty->setPropertyname(CustomProperty::createSlug($propertylabel)); + return $this->customPropertiesMapper->insert($customProperty); + } + + /** + * @param int $id + * @return CustomProperty + */ + public function delete(int $id): CustomProperty + { + $customProperty = $this->customPropertiesMapper->findById($id); + return $this->customPropertiesMapper->delete($customProperty); + } } \ No newline at end of file diff --git a/lib/Db/CustomPropertiesMapper.php b/lib/Db/CustomPropertiesMapper.php index 6806f61..1e0c71c 100644 --- a/lib/Db/CustomPropertiesMapper.php +++ b/lib/Db/CustomPropertiesMapper.php @@ -5,42 +5,47 @@ use OCP\AppFramework\Db\QBMapper; use OCP\IDBConnection; -class CustomPropertiesMapper extends QBMapper { - /** - * @param IDBConnection $db - */ - public function __construct(IDBConnection $db) { - parent::__construct($db, 'customproperties', CustomProperty::class); - } - - public function findAllForUser($userId) { - $qb = $this->db->getQueryBuilder(); - - $qb->select('*') - ->from($this->tableName) - ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))) - ->orWhere($qb->expr()->isNull('user_id')); - - return $this->findEntities($qb); - } - - public function findById(int $id) { - $qb = $this->db->getQueryBuilder(); - - $qb->select('*') - ->from($this->getTableName()) - ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); - - return $this->findEntity($qb); - } - - public function findAll() { - $qb = $this->db->getQueryBuilder(); - - $qb->select('*') - ->from($this->tableName) - ->where($qb->expr()->isNull('user_id')); - - return $this->findEntities($qb); - } +class CustomPropertiesMapper extends QBMapper +{ + /** + * @param IDBConnection $db + */ + public function __construct(IDBConnection $db) + { + parent::__construct($db, 'customproperties', CustomProperty::class); + } + + public function findAllForUser($userId) + { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->tableName) + ->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId))) + ->orWhere($qb->expr()->isNull('user_id')); + + return $this->findEntities($qb); + } + + public function findById(int $id) + { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->getTableName()) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); + + return $this->findEntity($qb); + } + + public function findAll() + { + $qb = $this->db->getQueryBuilder(); + + $qb->select('*') + ->from($this->tableName) + ->where($qb->expr()->isNull('user_id')); + + return $this->findEntities($qb); + } } \ No newline at end of file diff --git a/lib/Db/CustomProperty.php b/lib/Db/CustomProperty.php index 70d5097..f3eb3c5 100644 --- a/lib/Db/CustomProperty.php +++ b/lib/Db/CustomProperty.php @@ -4,22 +4,25 @@ use OCP\AppFramework\Db\Entity; -class CustomProperty extends Entity { - /** @var string */ - public $userId; - /** @var string */ - public $propertyname; - /** @var string */ - public $propertylabel; +class CustomProperty extends Entity +{ + /** @var string */ + public $userId; + /** @var string */ + public $propertyname; + /** @var string */ + public $propertylabel; - public function __construct() { - $this->addType('id', 'int'); - $this->addType('userId', 'string'); - $this->addType('propertyname', 'string'); - $this->addType('propertylabel', 'string'); - } + public function __construct() + { + $this->addType('id', 'int'); + $this->addType('userId', 'string'); + $this->addType('propertyname', 'string'); + $this->addType('propertylabel', 'string'); + } - public static function createSlug($propertylabel) { - return strtolower(trim(preg_replace('/[^A-Za-z0-9]+/', '', $propertylabel))); - } + public static function createSlug($propertylabel) + { + return strtolower(trim(preg_replace('/[^A-Za-z0-9]+/', '', $propertylabel))); + } } \ No newline at end of file diff --git a/lib/Db/PropertiesMapper.php b/lib/Db/PropertiesMapper.php index 5eae317..ba496d5 100644 --- a/lib/Db/PropertiesMapper.php +++ b/lib/Db/PropertiesMapper.php @@ -5,26 +5,30 @@ use OCP\AppFramework\Db\QBMapper; use OCP\IDBConnection; -class PropertiesMapper extends QBMapper { - /** - * @param IDBConnection $db - */ - public function __construct(IDBConnection $db) { - parent::__construct($db, 'properties', Property::class); - } - - public function findAllByPath(string $propertypath, string $uid) { - $qb = $this->db->getQueryBuilder(); - - $q = $qb->select('*') - ->from($this->tableName) - ->where($qb->expr()->eq('propertypath', $qb->createNamedParameter($propertypath))) - ->andWhere($qb->expr()->eq('userid', $qb->createNamedParameter($uid))); - - return $this->findEntities($q); - } - - public function findByPathAndName(string $propertypath, string $propertyname, string $uid): Property { +class PropertiesMapper extends QBMapper +{ + /** + * @param IDBConnection $db + */ + public function __construct(IDBConnection $db) + { + parent::__construct($db, 'properties', Property::class); + } + + public function findAllByPath(string $propertypath, string $uid) + { + $qb = $this->db->getQueryBuilder(); + + $q = $qb->select('*') + ->from($this->tableName) + ->where($qb->expr()->eq('propertypath', $qb->createNamedParameter($propertypath))) + ->andWhere($qb->expr()->eq('userid', $qb->createNamedParameter($uid))); + + return $this->findEntities($q); + } + + public function findByPathAndName(string $propertypath, string $propertyname, string $uid): Property + { $qb = $this->db->getQueryBuilder(); $q = $qb->select('*') diff --git a/lib/Db/Property.php b/lib/Db/Property.php index 688edb4..2bf8d3e 100644 --- a/lib/Db/Property.php +++ b/lib/Db/Property.php @@ -4,21 +4,23 @@ use OCP\AppFramework\Db\Entity; -class Property extends Entity { - /** @var string */ - public $userid; - /** @var string */ - public $propertypath; - /** @var string */ - public $propertyname; - /** @var string */ - public $propertyvalue; +class Property extends Entity +{ + /** @var string */ + public $userid; + /** @var string */ + public $propertypath; + /** @var string */ + public $propertyname; + /** @var string */ + public $propertyvalue; - public function __construct() { - $this->addType('id', 'int'); - $this->addType('userid', 'string'); - $this->addType('propertypath', 'string'); - $this->addType('propertyname', 'string'); - $this->addType('propertyvalue', 'string'); - } + public function __construct() + { + $this->addType('id', 'int'); + $this->addType('userid', 'string'); + $this->addType('propertypath', 'string'); + $this->addType('propertyname', 'string'); + $this->addType('propertyvalue', 'string'); + } } \ No newline at end of file diff --git a/lib/Migration/Version1000Date20200522000000.php b/lib/Migration/Version1000Date20200522000000.php index 8d138f8..d1ed922 100644 --- a/lib/Migration/Version1000Date20200522000000.php +++ b/lib/Migration/Version1000Date20200522000000.php @@ -4,41 +4,43 @@ use Closure; use OCP\DB\ISchemaWrapper; -use OCP\Migration\SimpleMigrationStep; use OCP\Migration\IOutput; +use OCP\Migration\SimpleMigrationStep; -class Version1000Date20200522000000 extends SimpleMigrationStep { - /** - * @param IOutput $output - * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` - * @param array $options - * @return null|ISchemaWrapper - */ - public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) { - /** @var ISchemaWrapper $schema */ - $schema = $schemaClosure(); +class Version1000Date20200522000000 extends SimpleMigrationStep +{ + /** + * @param IOutput $output + * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` + * @param array $options + * @return null|ISchemaWrapper + */ + public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) + { + /** @var ISchemaWrapper $schema */ + $schema = $schemaClosure(); - if (!$schema->hasTable('customproperties')) { - $table = $schema->createTable('customproperties'); - $table->addColumn('id', 'integer', [ - 'autoincrement' => true, - 'notnull' => true, - ]); - $table->addColumn('user_id', 'string', [ - 'notnull' => false, - 'length' => 200, - ]); - $table->addColumn('propertyname', 'string', [ - 'notnull' => true, - 'length' => 200 - ]); - $table->addColumn('propertylabel', 'string', [ - 'notnull' => true, - 'length' => 200 - ]); + if (!$schema->hasTable('customproperties')) { + $table = $schema->createTable('customproperties'); + $table->addColumn('id', 'integer', [ + 'autoincrement' => true, + 'notnull' => true, + ]); + $table->addColumn('user_id', 'string', [ + 'notnull' => false, + 'length' => 200, + ]); + $table->addColumn('propertyname', 'string', [ + 'notnull' => true, + 'length' => 200 + ]); + $table->addColumn('propertylabel', 'string', [ + 'notnull' => true, + 'length' => 200 + ]); - $table->setPrimaryKey(['id']); - } - return $schema; - } + $table->setPrimaryKey(['id']); + } + return $schema; + } } \ No newline at end of file diff --git a/lib/Service/PropertyService.php b/lib/Service/PropertyService.php index f5ae06c..d2567b2 100644 --- a/lib/Service/PropertyService.php +++ b/lib/Service/PropertyService.php @@ -6,76 +6,82 @@ use OCA\CustomProperties\Db\CustomPropertiesMapper; use OCA\CustomProperties\Db\PropertiesMapper; -class PropertyService { - const NS_PREFIX = "{http://owncloud.org/ns}"; +class PropertyService +{ + const NS_PREFIX = "{http://owncloud.org/ns}"; - /** - * @var CustomPropertiesMapper - */ - private $customPropertiesMapper; - /** - * @var PropertiesMapper - */ - private $propertiesMapper; + /** + * @var CustomPropertiesMapper + */ + private $customPropertiesMapper; + /** + * @var PropertiesMapper + */ + private $propertiesMapper; - public function __construct( - CustomPropertiesMapper $customPropertiesMapper, - PropertiesMapper $propertiesMapper - ) { - $this->customPropertiesMapper = $customPropertiesMapper; - $this->propertiesMapper = $propertiesMapper; - } + public function __construct( + CustomPropertiesMapper $customPropertiesMapper, + PropertiesMapper $propertiesMapper + ) + { + $this->customPropertiesMapper = $customPropertiesMapper; + $this->propertiesMapper = $propertiesMapper; + } - function getProperties($userId, $path, $name) { - $customProperties = $this->customPropertiesMapper->findAllForUser($userId); - $propertypath = ltrim(Filesystem::normalizePath("files/$userId/$path/$name"), "/"); - $properties = $this->propertiesMapper->findAllByPath($propertypath, $userId); + private static function normalizeProperty($prop) + { + $propertyname = str_replace(self::NS_PREFIX, "", $prop->getPropertyname()); + $propertyvalue = isset($prop->propertyvalue) ? $prop->propertyvalue : ""; + $propertylabel = isset($prop->propertylabel) ? $prop->propertylabel : $propertyname; - // Normalize the properties - $customProperties = array_map('self::normalizeProperty', $customProperties); - $properties = array_map('self::normalizeProperty', $properties); + return array( + "propertyname" => $propertyname, + "propertyvalue" => $propertyvalue, + "propertylabel" => $propertylabel + ); + } - $mergedProperties = self::merge_properties($customProperties, $properties); - foreach ($mergedProperties as $key => $mergedProperty) { - $mergedProperties[$key]['_knownproperty'] = self::find_property_with_name($customProperties, $mergedProperty['propertyname']) !== -1; - } - return $mergedProperties; - } + function getProperties($userId, $path, $name) + { + $customProperties = $this->customPropertiesMapper->findAllForUser($userId); + $propertypath = ltrim(Filesystem::normalizePath("files/$userId/$path/$name"), "/"); + $properties = $this->propertiesMapper->findAllByPath($propertypath, $userId); - private static function normalizeProperty($prop) { - $propertyname = str_replace(self::NS_PREFIX, "", $prop->getPropertyname()); - $propertyvalue = isset($prop->propertyvalue) ? $prop->propertyvalue : ""; - $propertylabel = isset($prop->propertylabel) ? $prop->propertylabel : $propertyname; + // Normalize the properties + $customProperties = array_map('self::normalizeProperty', $customProperties); + $properties = array_map('self::normalizeProperty', $properties); - return array( - "propertyname" => $propertyname, - "propertyvalue" => $propertyvalue, - "propertylabel" => $propertylabel - ); - } + $mergedProperties = self::merge_properties($customProperties, $properties); + foreach ($mergedProperties as $key => $mergedProperty) { + $mergedProperties[$key]['_knownproperty'] = self::find_property_with_name($customProperties, $mergedProperty['propertyname']) !== -1; + } + return $mergedProperties; + } - private static function merge_properties(array $customProperties, array $properties) { - $result = $customProperties; + private static function merge_properties(array $customProperties, array $properties) + { + $result = $customProperties; - foreach ($properties as $customProperty) { - $index = self::find_property_with_name($result, $customProperty['propertyname']); - if ($index === -1) { - $result[] = $customProperty; - } else { - $result[$index]['propertyvalue'] = $customProperty['propertyvalue']; - } - } + foreach ($properties as $customProperty) { + $index = self::find_property_with_name($result, $customProperty['propertyname']); + if ($index === -1) { + $result[] = $customProperty; + } else { + $result[$index]['propertyvalue'] = $customProperty['propertyvalue']; + } + } - return $result; - } + return $result; + } - private static function find_property_with_name(array $arr, string $name) { - foreach ($arr as $idx => $prop) { - if ($prop['propertyname'] === $name) { - return $idx; - } - } + private static function find_property_with_name(array $arr, string $name) + { + foreach ($arr as $idx => $prop) { + if ($prop['propertyname'] === $name) { + return $idx; + } + } - return -1; - } + return -1; + } } \ No newline at end of file