EntityRepository Class This class serves as the base repository for entity data access and manipulation. It provides methods for retrieving, formatting, and saving entity data to the database. The repository pattern implemented here abstracts the data access logic from the entity classes, allowing for better separation of concerns and more maintainable code. DEBEUG INSTRUCTIONS : display $array_attributes to see the attributes of the entity
function __construct() {
// Initialize properties if not already set by child class
if (!isset($this->datas)) {
$this->datas = [];
}
if (!isset($this->array_attributes)) {
$this->array_attributes = [];
}
}
đ§ __construct
function __construct() {
// Initialize properties if not already set by child class
if (!isset($this->datas)) {
$this->datas = [];
}
if (!isset($this->array_attributes)) {
$this->array_attributes = [];
}
}
đ§ __construct
function __construct() {
// Initialize properties if not already set by child class
if (!isset($this->datas)) {
$this->datas = [];
}
if (!isset($this->array_attributes)) {
$this->array_attributes = [];
}
}
đ§ __construct
function __construct() {
// Initialize properties if not already set by child class
if (!isset($this->datas)) {
$this->datas = [];
}
if (!isset($this->array_attributes)) {
$this->array_attributes = [];
}
}
đ§ __construct
function __construct() {
// Initialize properties if not already set by child class
if (!isset($this->datas)) {
$this->datas = [];
}
if (!isset($this->array_attributes)) {
$this->array_attributes = [];
}
}
đ§ __construct
Constructor to ensure all necessary properties are initialized
function __construct() {
// Initialize properties if not already set by child class
if (!isset($this->datas)) {
$this->datas = [];
}
if (!isset($this->array_attributes)) {
$this->array_attributes = [];
}
}
đ§ find
Retrieves data from the database and populates entity properties This method fetches object attributes from the database using the provided type ID and object ID, then formats them and stores them in the entity.
function find($type_id, $id_obje, $entity)
{
try {
// Check if required functions exist
if (!function_exists('fwc7_data_objet_att')) {
throw new Exception("Required function 'fwc7_data_objet_att' is not available.");
}
// Get object attributes from the database
$attributes = fwc7_data_objet_att('', $type_id, $id_obje);
if (!is_array($attributes)) {
throw new Exception("Failed to retrieve object attributes for type $type_id and object $id_obje.");
}
// Format the attributes
$formatted_attributes = $this->format_attributes($attributes, $type_id);
// ... (truncated)
âī¸ Parameters
$type_id(int) The parameter type identifier
$id_obje(int) The object instance identifier
$entity(object) The entity to populate
âŠī¸ Returns
(array) The retrieved data
â ī¸ Throws
Exception: If data retrieval fails
đ§ save
Saves entity data to the database This method persists the entity data to the database using the provided type ID and object ID. If these are not provided, it attempts to retrieve them from the entity itself.
function save($type_id = null, $id_obje = null, $entity = null, $data = null) {
try {
// Check if required function exists
if (!function_exists('fwc7_modify_att_edit')) {
throw new Exception("Required function 'fwc7_modify_att_edit' is not available.");
}
// Determine which entity to use
$entityToUse = $entity ?? $this->entity;
if ($entityToUse === null) {
throw new Exception("No entity provided and no entity is stored in the repository.");
}
// Determine type_id and id_obje
$typeIdToUse = $type_id;
// ... (truncated)
âī¸ Parameters
$type_id(int|null) The parameter type identifier (optional)
$id_obje(int|null) The object instance identifier (optional)
$entity(object|null) The entity to save (optional)
$data(array|null) The data to save (optional)
âŠī¸ Returns
(bool) True on success, false on failure
â ī¸ Throws
Exception: If there's an error during save operation
đ§ initializeProperties
Initializes object properties from attributes This method populates the entity's properties with values from the formatted attributes data. It handles special cases like workflow fields that require additional processing. It can use reflection and annotations to map attributes to properties.
function initializeProperties($datas) {
try {
// Store original data in array_attributes for backward compatibility
if (property_exists($this, 'array_attributes')) {
$this->array_attributes = $datas;
}
if (!is_array($datas) || empty($datas)) {
return; // Nothing to do with empty data
}
try{
$this->_enhancedInitializeFromAnnotations($datas);
}catch(Exception $e){
// ... (truncated)
âī¸ Parameters
$datas(array) The formatted attributes data
â ī¸ Throws
Exception: If property initialization fails
đ§ _legacyInitializeFromAttributes
Legacy method for initializing properties from attributes (Internal implementation)
function _legacyInitializeFromAttributes($attributes) {
if (!is_array($attributes)) {
return;
}
foreach ($attributes as $property => $data) {
$propertyName = $this->sanitizePropertyName($property);
if (empty($propertyName) || !property_exists($this, $propertyName)) {
continue;
}
// Extract value based on format
$value = isset($data["value"]) ? $data["value"] : $data;
// ... (truncated)
âī¸ Parameters
$attributes(array) Array of attributes with their values
âŠī¸ Returns
(void)
đ§ _enhancedInitializeFromAnnotations
Enhanced method for initializing properties using annotations (Internal implementation)
function _enhancedInitializeFromAnnotations($datas) {
// Extract raw attribute data based on format
$attributeData = [];
// Detect data format
$firstKey = key($datas);
$firstValue = reset($datas);
if (is_array($firstValue) && isset($firstValue['attribute']) && isset($firstValue['value'])) {
// Format: property => [attribute => X, value => Y]
foreach ($datas as $property => $data) {
if (isset($data["attribute"]) && isset($data["value"])) {
$attributeData[$data["attribute"]] = $data["value"];
}
}
// ... (truncated)
âī¸ Parameters
$datas(array) Array of attributes with their values
âŠī¸ Returns
(void)
đ§ sanitizeData
Sanitizes data before saving This method cleans the data to prevent potential security issues like SQL injection or other attacks.
function sanitizeData($data) {
$sanitized = [];
foreach ($data as $key => $value) {
if (is_string($value)) {
// Remove null bytes which can be used in some injection attacks
$sanitized[$key] = str_replace(chr(0), '', $value);
} else {
$sanitized[$key] = $value;
}
}
return $sanitized;
// ... (truncated)
âī¸ Parameters
$data(array) Data to sanitize
âŠī¸ Returns
(array) Sanitized data
đ§ format_attributes
Formats attributes into a standardized structure This method transforms raw attribute data into a standardized format with sanitized property names. It handles special cases like transliteration and ensures unique property names.
function format_attributes($attributes, $id_type) {
if (!is_array($attributes)) {
throw new Exception("Invalid attributes parameter: must be an array");
}
$result = [];
$usedTitles = [];
$attributeNameMapping = []; // Track which attribute name maps to which title
foreach ($attributes as $key => $value) {
try {
// If we've already processed this attribute, use consistent naming
if (isset($attributeNameMapping[$key])) {
// ... (truncated)
âī¸ Parameters
$attributes(array) Raw attributes array
$id_type(int) Parameter type ID
âŠī¸ Returns
(array) Formatted attributes array with sanitized keys
â ī¸ Throws
Exception: If formatting fails
đ§ sanitizePropertyName
Sanitizes property names to ensure valid PHP variable names This method ensures that property names are valid PHP identifiers by removing invalid characters and ensuring they start with a letter or underscore.
function sanitizePropertyName($property) {
// Remove any characters that aren't valid in PHP variable names
$sanitized = preg_replace('/[^a-zA-Z0-9_]/', '', $property);
// Ensure the name starts with a letter or underscore
if (!empty($sanitized) && !preg_match('/^[a-zA-Z_]/', $sanitized)) {
$sanitized = '_' . $sanitized;
}
return $sanitized;
}
âī¸ Parameters
$property(string) Raw property name
âŠī¸ Returns
(string) Sanitized property name
đ§ get_array_attributes
Gets the array of attributes
function get_array_attributes() {
return $this->array_attributes;
}
âŠī¸ Returns
(array) The array of attributes
đ§ set_array_attributes
Sets the array of attributes
function set_array_attributes($array_attributes) {
$this->array_attributes = $array_attributes;
}
âī¸ Parameters
$array_attributes(array) The array of attributes
đ§ get_id_type
Gets the ID type
function get_id_type() {
return $this->id_type;
}
âŠī¸ Returns
(int) The ID type
đ§ findAll
Finds all entities of the current type This method retrieves all entities of the current type from the database and returns them as an array.
$parse_object(bool) Whether to parse the objects or return raw data
âŠī¸ Returns
(array) All entities of the current type
đ§ findBy
Finds entities of the current type matching specified criteria Example: $manager->findBy(["Calendarevent" => "caldav.php/zaezaeaz"])
function findBy(array $whereClause = [], string $limit = "30", string $active = "1",
bool $parse_object = true, string $orderBy = "", string $orderDirection = "") {
// Convert property names to attribute names
$attributeWhereClause = [];
foreach ($whereClause as $property => $value) {
// fwk_dump($property,"property");
// Try to get the attribute name for this property
$attributeName = $this->getAttributeNameForProperty($property);
// fwk_dump($attributeName,"attributeName");
// If no attribute mapping found by annotation, assume the property name is the attribute name
if ($attributeName === null) {
$attributeName = $property;
}
if($attributeName == "id_work"){
$value = $this->findStatusCode($value);
// ... (truncated)
âī¸ Parameters
$whereClause(array) Associative array of property => value pairs for filtering
$limit(string) Maximum number of results to return
$active(string) The active status of the entities (1=active, 0=inactive, empty=all)
$parse_object(bool) Whether to parse the objects or return raw data
$orderBy(string) Field name to order by
$orderDirection(string) Sort direction ("ASC" or "DESC")
âŠī¸ Returns
(array) Entities matching the criteria
â ī¸ Throws
Exception: If conversion from property to attribute name fails
đ§ mapAttributesToProperties
Maps database attributes to entity properties using annotations This method uses reflection to find @attribute annotations on properties and maps the provided data array accordingly.
function mapAttributesToProperties($attributeData) {
try {
if (!is_array($attributeData)) {
throw new Exception("Attribute data must be an array");
}
// Create a mapping of attribute names to property names
$attributeToProperties = [];
// Get all properties with attribute annotations
$reflection = new \ReflectionClass($this);
foreach ($reflection->getProperties() as $property) {
$docComment = $property->getDocComment();
// Extract attribute name from docblock
if (preg_match('/@attribute\s+([^\s]+)/', $docComment, $matches)) {
// ... (truncated)
âī¸ Parameters
$attributeData(array) Array of attribute data (attribute name => value)
âŠī¸ Returns
($this) For method chaining
đ§ getAttributeNameForProperty
Gets the database attribute name for a given property Uses reflection to read the @attribute annotation from the property docblock
(string|null) The attribute name or null if not found
đ§ getAllAttributeMappings
Gets all property-to-attribute mappings for this entity
function getAllAttributeMappings() {
$mappings = [];
$reflection = new \ReflectionClass($this);
foreach ($reflection->getProperties() as $property) {
$propertyName = $property->getName();
$docComment = $property->getDocComment();
if (preg_match('/@attribute\s+([^\s]+)/', $docComment, $matches)) {
$mappings[$propertyName] = $matches[1];
}
}
// ... (truncated)
âŠī¸ Returns
(array) Associative array where keys are property names and values are attribute names
đ§ logError
Logs errors without breaking functionality This helper function logs errors in a consistent way while allowing for code to continue execution for legacy compatibility.
function logError($message, $exception = null, $throwException = false) {
$errorMessage = $message;
if ($exception !== null) {
$errorMessage .= ": " . $exception->getMessage();
}
// Log the error
error_log("[CalDav EntityManager] " . $errorMessage);
// Optionally throw the exception
if ($throwException) {
if ($exception !== null) {
throw $exception;
} else {
// ... (truncated)
âī¸ Parameters
$message(string) The error message to log
$exception(Exception|null) Optional exception to include in the log
$throwException(bool) Whether to throw the exception or just log it
â ī¸ Throws
Exception: If throwException is true
đ§ findStatusCode
Find entities by their workflow status
function findStatusCode($status) {
// Get the workflow ID for the given status name
$workflow_data = null;
if (function_exists("fwc7_param_objet_workflow")) {
// Get all workflows for this entity type
$workflows = fwp7_param_objet_work_list("", $this->id_type, "","");
// Find the workflow ID that matches the status name
foreach ($workflows as $id_work => $workflow) {
if ($workflow['module_code'] === $status) {
$workflow_data = $workflow;
break;
}
}
// ... (truncated)