public function createSubject(SubjectConfigurationInterface $subjectConfiguration)
    {

        // load the subject instance from the DI container and set the subject configuration
        $subjectInstance = $this->container->get($subjectConfiguration->getId());
        $subjectInstance->setConfiguration($subjectConfiguration);

        // load the import adapter instance from the DI container and set it on the subject instance
        $importAdapter = $this->container->get($subjectConfiguration->getImportAdapter()->getId());

        // query whether or not we've found a factory or the instance itself
        if ($importAdapter instanceof ImportAdapterInterface) {
            $subjectInstance->setImportAdapter($importAdapter);
            // log a warning, that this is deprecated
            $this->getSystemLogger()->warning(
                sprintf(
                    'Direct injection of import adapter with DI ID "%s" is deprecated since version 3.0.0, please use factory instead',
                    $subjectConfiguration->getImportAdapter()->getId()
                )
            );
        } elseif ($importAdapter instanceof ImportAdapterFactoryInterface) {
            $subjectInstance->setImportAdapter($importAdapter->createImportAdapter($subjectConfiguration));
        } else {
            throw new \Exception(
                sprintf(
                    'Expected either an instance of ImportAdapterInterface or ImportAdapterFactoryInterface for DI ID "%s"',
                    $subjectConfiguration->getImportAdapter()->getId()
                )
            );
        }

        // query whether or not we've a subject instance that implements the exportable subject interface
        if ($subjectInstance instanceof ExportableSubjectInterface) {
            // load the export adapter instance from the DI container and set it on the subject instance
            $exportAdapter = $this->container->get($subjectConfiguration->getExportAdapter()->getId());

            // query whether or not we've found a factory or the instance itself
            if ($exportAdapter instanceof ExportAdapterInterface) {
                // inject the export adapter into the subject
                $subjectInstance->setExportAdapter($exportAdapter);
                // log a warning, that this is deprecated
                $this->getSystemLogger()->warning(
                    sprintf(
                        'Direct injection of export adapter with DI ID "%s" is deprecated since version 3.0.0, please use factory instead',
                        $subjectConfiguration->getExportAdapter()->getId()
                    )
                );
            } elseif ($exportAdapter instanceof ExportAdapterFactoryInterface) {
                $subjectInstance->setExportAdapter($exportAdapter->createExportAdapter($subjectConfiguration));
            } else {
                throw new \Exception(
                    sprintf(
                        'Expected either an instance of ExportAdapterInterface or ExportAdapterFactoryInterface for DI ID "%s"',
                        $subjectConfiguration->getExportAdapter()->getId()
                    )
                );
            }
        }

        // load te number converter instance from the DI container and set it on the subject instance
        if ($subjectInstance instanceof NumberConverterSubjectInterface) {
            $subjectInstance->setNumberConverter($this->numberConverterFactory->createNumberConverter($subjectConfiguration));
        }

        // load te date converter instance from the DI container and set it on the subject instance
        if ($subjectInstance instanceof DateConverterSubjectInterface) {
            $subjectInstance->setDateConverter($this->dateConverterFactory->createDateConverter($subjectConfiguration));
        }

        // load the filesystem adapter instance from the DI container and set it on the subject instance
        if ($subjectInstance instanceof FilesystemSubjectInterface) {
            $filesystemAdapterFactory = $this->container->get($subjectConfiguration->getFilesystemAdapter()->getId());
            $subjectInstance->setFilesystemAdapter($filesystemAdapterFactory->createFilesystemAdapter($subjectConfiguration));
        }

        // return the initialized subject instance
        return $subjectInstance;
    }

Factory method to create new subject instance.

@param \TechDivision\Import\Configuration\SubjectConfigurationInterface $subjectConfiguration The subject configuration

@return \TechDivision\Import\Subjects\SubjectInterface The subject instance

Factory method to create new subject instance .


public function createSerializer(CsvConfigurationInterface $configuration)
    {

        // load the serializer instance from the container and pass the configuration
        /** @var \TechDivision\Import\Serializers\ConfigurationAwareSerializerInterface $serializer */
        $serializer = $this->container->get(DependencyInjectionKeys::IMPORT_SERIALIZER_CSV_ADDITIONAL_ATTRIBUTE);
        $serializer->init($configuration);

        // return the serializer instance
        return $serializer;
    }

Creates and returns the serializer instance.

@param \TechDivision\Import\Configuration\CsvConfigurationInterface $configuration The CSV configuration

@return \TechDivision\Import\Serializers\ConfigurationAwareSerializerInterface The serializer instance

Creates and returns the serializer instance .


public function findAllByEntityTypeIdAndAttributeSetName($entityTypeId, $attributeSetName)
    {

        // initialize the params
        $params = array(
            MemberNames::ENTITY_TYPE_ID     => $entityTypeId,
            MemberNames::ATTRIBUTE_SET_NAME => $attributeSetName
        );

        // initialize the array for the EAV attributes
        $eavAttributes = array();

        // execute the prepared statement and return the array with the EAV attributes
        $this->eavAttributesByEntityTypeIdAndAttributeSetNameStmt->execute($params);

        // load the available EAV attributes
        $availableEavAttributes = $this->eavAttributesByEntityTypeIdAndAttributeSetNameStmt->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($availableEavAttributes as $eavAttribute) {
            $eavAttributes[$eavAttribute[MemberNames::ATTRIBUTE_CODE]] = $eavAttribute;
        }

        // return the array with the EAV attributes
        return $eavAttributes;
    }

Return's an array with the available EAV attributes for the passed entity type ID and attribute set name.

@param integer $entityTypeId     The entity type ID of the EAV attributes to return
@param string  $attributeSetName The attribute set name of the EAV attributes to return

@return array The array with all available EAV attributes

Return s an array with the available EAV attributes for the passed entity type ID and attribute set name .


public function findAllByOptionValueAndStoreId($optionValue, $storeId)
    {

        // initialize the params
        $params = array(
            MemberNames::VALUE    => $optionValue,
            MemberNames::STORE_ID => $storeId
        );

        // execute the prepared statement and return the array with the EAV attributes
        $this->eavAttributesByOptionValueAndStoreIdStmt->execute($params);
        return $this->eavAttributesByOptionValueAndStoreIdStmt->fetchAll(\PDO::FETCH_ASSOC);
    }

Return's an array with the available EAV attributes for the passed option value and store ID.

@param string $optionValue The option value of the EAV attributes
@param string $storeId     The store ID of the EAV attribues

@return array The array with all available EAV attributes

Return s an array with the available EAV attributes for the passed option value and store ID .


public function findAllByIsUserDefined($isUserDefined = 1)
    {

        // initialize the array for the EAV attributes
        $eavAttributes = array();

        // initialize the params
        $params = array(MemberNames::ID_USER_DEFINED => $isUserDefined);

        // execute the prepared statement and return the array with the EAV attributes
        $this->eavAttributesByUserDefinedStmt->execute($params);

        // load the available EAV attributes
        $availableEavAttributes = $this->eavAttributesByUserDefinedStmt->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($availableEavAttributes as $eavAttribute) {
            $eavAttributes[$eavAttribute[MemberNames::ATTRIBUTE_CODE]] = $eavAttribute;
        }

        // return the array with the EAV attributes
        return $eavAttributes;
    }

Return's an array with the available EAV attributes for the passed is user defined flag.

@param integer $isUserDefined The flag itself

@return array The array with the EAV attributes matching the passed flag

Return s an array with the available EAV attributes for the passed is user defined flag .


public function findAllByEntityTypeIdAndIsUserDefined($entityTypeId, $isUserDefined = 1)
    {

        // initialize the array for the EAV attributes
        $eavAttributes = array();

        // initialize the params
        $params = array(
            MemberNames::ENTITY_TYPE_ID  => $entityTypeId,
            MemberNames::ID_USER_DEFINED => $isUserDefined
        );

        // execute the prepared statement and return the array with the EAV attributes
        $this->eavAttributesByEntityTypeIdAndUserDefinedStmt->execute($params);

        // load the available EAV attributes
        $availableEavAttributes = $this->eavAttributesByEntityTypeIdAndUserDefinedStmt->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($availableEavAttributes as $eavAttribute) {
            $eavAttributes[$eavAttribute[MemberNames::ATTRIBUTE_CODE]] = $eavAttribute;
        }

        // return the array with the EAV attributes
        return $eavAttributes;
    }

Return's an array with the available EAV attributes for the passed is entity type and
user defined flag.

@param integer $entityTypeId  The entity type ID of the EAV attributes to return
@param integer $isUserDefined The flag itself

@return array The array with the EAV attributes matching the passed entity type and user defined flag

Return s an array with the available EAV attributes for the passed is entity type and user defined flag .


public function findAllByEntityTypeId($entityTypeId)
    {

        // initialize the array for the EAV attributes
        $eavAttributes = array();

        // execute the prepared statement and return the array with the EAV attributes
        $this->eavAttributesByEntityTypeIdAndUserDefinedStmt->execute(array(MemberNames::ENTITY_TYPE_ID  => $entityTypeId));

        // load the available EAV attributes
        $availableEavAttributes = $this->eavAttributesByEntityTypeIdAndUserDefinedStmt->fetchAll(\PDO::FETCH_ASSOC);
        foreach ($availableEavAttributes as $eavAttribute) {
            $eavAttributes[$eavAttribute[MemberNames::ATTRIBUTE_CODE]] = $eavAttribute;
        }

        // return the array with the EAV attributes
        return $eavAttributes;
    }

Return's an array with the available EAV attributes for the passed is entity type.

@param integer $entityTypeId The entity type ID of the EAV attributes to return

@return array The array with the EAV attributes matching the passed entity type

Return s an array with the available EAV attributes for the passed is entity type .


public function findOneByOptionValueAndStoreId($optionValue, $storeId)
    {

        // execute the prepared statement and return the array with the fail EAV attributes
        if (sizeof($eavAttributes = $this->findAllByOptionValueAndStoreId($optionValue, $storeId)) > 0) {
            return reset($eavAttributes);
        }
    }

Return's the first EAV attribute for the passed option value and store ID.

@param string $optionValue The option value of the EAV attributes
@param string $storeId     The store ID of the EAV attribues

@return array The array with the EAV attribute

Return s the first EAV attribute for the passed option value and store ID .


protected function prepareObservers(SubjectInterface $subject, array $observers, $type = null)
    {

        // iterate over the array with observers and prepare them
        foreach ($observers as $key => $observer) {
            // we have to initialize the type only on the first level
            if ($type == null) {
                $type = $key;
            }

            // query whether or not we've an subarry or not
            if (is_array($observer)) {
                $this->prepareObservers($subject, $observer, $type);
            } else {
                $subject->registerObserver($this->container->get($observer), $type);
            }
        }
    }

Prepare the observers defined in the system configuration.

@param \TechDivision\Import\Subjects\SubjectInterface $subject   The subject to prepare the observers for
@param array                                          $observers The array with the observers
@param string                                         $type      The actual observer type

@return void

Prepare the observers defined in the system configuration .


public function resolvePath($path)
    {

        // if we've an absolute path, return it immediately
        if ($this->getFilesystemAdapter()->isDir($path)) {
            return $path;
        }

        // temporarily save the path
        $originalPath = $path;

        // try to prepend the actual working directory, assuming we've a relative path
        if ($this->getFilesystemAdapter()->isDir($path = getcwd() . DIRECTORY_SEPARATOR . ltrim($path, '/'))) {
            return $path;
        }

        // throw an exception if the passed directory doesn't exists
        throw new \InvalidArgumentException(
            sprintf('Directory %s doesn\'t exist', $originalPath)
        );
    }

This method tries to resolve the passed path and returns it. If the path
is relative, the actual working directory will be prepended.

@param string $path The path to be resolved

@return string The resolved path
@throws \InvalidArgumentException Is thrown, if the path can not be resolved

This method tries to resolve the passed path and returns it . If the path is relative the actual working directory will be prepended .


public function mkdir($pathname, $mode = 0700, $recursive = false)
    {
        return $this->getFilesystemAdapter()->mkdir($pathname, $mode, $recursive);
    }

public function mkdir ( $ pathname , $ mode = 0700 , $ recursive = false ) { return $ this -> getFilesystemAdapter ( ) -> mkdir ( $ pathname , $ mode , $ recursive ) ; }

Creates a new directroy.

@param string  $pathname  The directory path
@param integer $mode      The mode is 0777 by default, which means the widest possible access
@param string  $recursive Allows the creation of nested directories specified in the pathname

@return boolean TRUE on success, else FALSE
@link http://php.net/mkdir


public function setAttribute($key, $value)
    {

        // query whether or not the key has already been used
        if (isset($this->attributes[$key])) {
            throw new \Exception(sprintf('Try to override data with key %s', $key));
        }

        // set the attribute in the registry
        $this->attributes[$key] = $value;
    }

Register the passed attribute under the specified key in the registry.

@param mixed $key   The key to register the value with
@param mixed $value The value to be registered

@return void
@throws \Exception Is thrown, if the key has already been used

Register the passed attribute under the specified key in the registry .


public function raiseCounter($key, $counterName)
    {

        // raise/initialize the value
        if (isset($this->attributes[$key][$counterName])) {
            $this->attributes[$key][$counterName]++;
        } else {
            $this->attributes[$key][$counterName] = 1;
        }

        // return the new value
        return $this->attributes[$key][$counterName];
    }

public
function
raiseCounter
(
$
key
,
$
counterName
)
{
// raise/initialize the value
if
(
isset
(
$
this
->
attributes
[
$
key
]
[
$
counterName
]
)
)
{
$
this
->
attributes
[
$
key
]
[
$
counterName
]
++
;
}
else
{
$
this
->
attributes
[
$
key
]
[
$
counterName
]
=
1
;
}
// return the new value
return
$
this
->
attributes
[
$
key
]
[
$
counterName
]
;
}

Raises the value for the attribute with the passed key by one.

@param mixed $key         The key of the attribute to raise the value for
@param mixed $counterName The name of the counter to raise

@return integer The counter's new value

Raises the value for the attribute with the passed key by one .


public function mergeAttributesRecursive($key, array $attributes)
    {

        // if the key not exists, simply add the new attributes
        if (!isset($this->attributes[$key])) {
            $this->attributes[$key] = $attributes;
            return;
        }

        // if the key exists and the value is an array, merge it with the passed array
        if (isset($this->attributes[$key]) && is_array($this->attributes[$key])) {
            $this->attributes[$key] = array_replace_recursive($this->attributes[$key], $attributes);
            return;
        }

        // throw an exception if the key exists, but the found value is not of type array
        throw new \Exception(sprintf('Can\'t merge attributes, because value for key %s already exists, but is not of type array', $key));
    }

This method merges the passed attributes with an array that
has already been added under the passed key.

If no value will be found under the passed key, the attributes
will simply be registered.

@param mixed $key        The key of the attributes that has to be merged with the passed ones
@param array $attributes The attributes that has to be merged with the exising ones

@return void
@throws \Exception Is thrown, if the already registered value is no array
@link http://php.net/array_replace_recursive

This method merges the passed attributes with an array that has already been added under the passed key .


public function createFilesystemAdapter(SubjectConfigurationInterface $subjectConfiguration)
    {

        // the filesystem adapter configuration
        $filesystemAdapterConfiguration = $subjectConfiguration->getFilesystemAdapter();

        // load the filesystem adapter's adapter configuration (FS specific)
        $adapterConfiguration = $filesystemAdapterConfiguration->getAdapter();

        // load the adapter parameters
        $adapterParams = $adapterConfiguration->getParams();

        // initialize the root directory, if not specified in the adapter parameters
        if (!isset($adapterParams[ConfigurationKeys::ROOT])) {
            $adapterParams[ConfigurationKeys::ROOT] = getcwd();
        }

        // load the adapter to use
        $reflectionClass = new \ReflectionClass($adapterConfiguration->getType());
        $adapter =  $reflectionClass->newInstanceArgs(ConfigurationUtil::prepareConstructorArgs($reflectionClass, $adapterParams));

        // create a new filesystem instance
        return new LeagueFilesystemAdapter(new Filesystem($adapter));
    }

Factory method to create new filesystem adapter instance.

@param \TechDivision\Import\Configuration\SubjectConfigurationInterface $subjectConfiguration The subject configuration

@return \TechDivision\Import\Adapter\FilesystemAdapterInterface The filesystem adapter instance

Factory method to create new filesystem adapter instance .


public function findAllByStoreView($storeViewId)
    {
        // try to load the categories and return them
        $this->categoriesByStoreViewStmt->execute(array(MemberNames::STORE_ID => $storeViewId));
        return $this->categoriesByStoreViewStmt->fetchAll(\PDO::FETCH_ASSOC);
    }

Return's an array with all available categories by store view ID.

@param integer $storeViewId The store view ID to return the categories for

@return array The available categories for the passed store view ID

Return s an array with all available categories by store view ID .


public function findAllRootCategories()
    {

        // try to load the categories
        $this->rootCategoriesStmt->execute();

        // initialize the array with the store code as key
        $rootCategories = array();

        // load the available root categories
        $availableRootCategories = $this->rootCategoriesStmt->fetchAll(\PDO::FETCH_ASSOC);

        // prepare the array with the root categories
        foreach ($availableRootCategories as $category) {
            $rootCategories[$category[MemberNames::CODE]] = $category;
        }

        // append the root categories to the cache
        return $rootCategories;
    }

Return's an array with the root categories with the store code as key.

@return array The root categories

Return s an array with the root categories with the store code as key .


public function createEmitter()
    {

        // initialize the event emitter
        $emitter = new Emitter();

        // load the listener configuration from the configuration
        $availableListeners = $this->configuration->getListeners();

        // load, initialize and add the configured listeners to the emitter
        foreach ($availableListeners as $listeners) {
            $this->prepareListeners($emitter, $listeners);
        }

        // load the available operations from the configuration
        $availableOperations = $this->configuration->getOperations();

        // load, initialize and add the configured listeners for the actual operation
        /** @var \TechDivision\Import\Configuration\OperationConfigurationInterface $operation */
        foreach ($availableOperations as $operation) {
            if ($operation->equals($this->configuration->getOperation())) {
                // load the operation's listeners
                $operationListeners = $operation->getListeners();
                // prepare the operation's listeners
                foreach ($operationListeners as $listeners) {
                    $this->prepareListeners($emitter, $listeners);
                }
            }
        }

        // return the initialized emitter instance
        return $emitter;
    }

The factory method that creates a new emitter instance.

@return void

The factory method that creates a new emitter instance .


protected function prepareListeners(EmitterInterface $emitter, array $listeners, $eventName = null)
    {

        // iterate over the array with listeners and prepare them
        foreach ($listeners as $key => $listener) {
            // we have to initialize the event name only on the first level
            if ($eventName == null) {
                $eventName = $key;
            }
            // query whether or not we've an subarray or not
            if (is_array($listener)) {
                $this->prepareListeners($emitter, $listener, $eventName);
            } else {
                $emitter->addListener($eventName, $this->container->get($listener));
            }
        }
    }

Prepare the listeners defined in the system configuration.

@param \League\Event\EmitterInterface $emitter   The event emitter to prepare the listeners for
@param array                          $listeners The array with the listeners
@param string                         $eventName The actual event name

@return void

Prepare the listeners defined in the system configuration .


protected function removeDir($src)
    {

        // open the directory
        $dir = opendir($src);

        // remove files/folders recursively
        while (false !== ($file = readdir($dir))) {
            if (($file != '.') && ($file != '..')) {
                $full = $src . '/' . $file;
                if (is_dir($full)) {
                    $this->removeDir($full);
                } else {
                    if (!unlink($full)) {
                        throw new \Exception(sprintf('Can\'t remove file %s', $full));
                    }
                }
            }
        }

        // close handle and remove directory itself
        closedir($dir);
        if (!rmdir($src)) {
            throw new \Exception(sprintf('Can\'t remove directory %s', $src));
        }
    }

Removes the passed directory recursively.

@param string $src Name of the directory to remove

@return void
@throws \Exception Is thrown, if the directory can not be removed

Removes the passed directory recursively .


protected function getSwiftMailer()
    {

        // the swift mailer configuration
        if ($swiftMailerConfiguration = $this->getPluginConfiguration()->getSwiftMailer()) {
            // load the factory that creates the swift mailer instance
            $factory = $swiftMailerConfiguration->getFactory();
            // create the swift mailer instance
            return $factory::factory($swiftMailerConfiguration);
        }
    }

Return's the configured swift mailer instance.

@return \Swift_Mailer|null The mailer instance

Return s the configured swift mailer instance .


protected function initialize($serial)
    {

        // load the actual status
        $status = $this->getRegistryProcessor()->getAttribute($serial);

        // query whether or not the configured source directory is available
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
            throw new \Exception(sprintf('Configured source directory "%s" is not available!', $sourceDir));
        }

        // set the source directory
        $this->setSourceDir($sourceDir);
    }

Initializes the file resolver for the import process with the passed serial.

@param string $serial The unique identifier of the actual import process

@return void
@throws \Exception Is thrown if the configured source directory is not available

Initializes the file resolver for the import process with the passed serial .


public function loadFiles($serial)
    {

        // clear the filecache
        clearstatcache();

        // initialize the resolver
        $this->initialize($serial);

        // initialize the array with the files matching the suffix found in the source directory
        $files = glob(sprintf('%s/*.%s', $this->getSourceDir(), $this->getSuffix()));

        // sort the files for the apropriate order
        usort($files, function ($a, $b) {
            return strcmp($a, $b);
        });

        // return the sorted files
        return $files;
    }

Loads the files from the source directory and return's them sorted.

@param string $serial The unique identifier of the actual import process

@return array The array with the files matching the subjects suffix
@throws \Exception Is thrown, when the source directory is NOT available

Loads the files from the source directory and return s them sorted .


protected function getStatements()
    {
        return array(
            SqlStatementKeys::DELETE_URL_REWRITE => $this->loadStatement(SqlStatementKeys::DELETE_URL_REWRITE),
            SqlStatementKeys::DELETE_URL_REWRITE_BY_SKU => $this->loadStatement(SqlStatementKeys::DELETE_URL_REWRITE_BY_SKU),
            SqlStatementKeys::DELETE_URL_REWRITE_BY_PATH => $this->loadStatement(SqlStatementKeys::DELETE_URL_REWRITE_BY_PATH),
            SqlStatementKeys::DELETE_URL_REWRITE_BY_CATEGORY_ID => $this->loadStatement(SqlStatementKeys::DELETE_URL_REWRITE_BY_CATEGORY_ID)
        );
    }

protected function getStatements ( ) { return array ( SqlStatementKeys :: DELETE_URL_REWRITE => $ this -> loadStatement ( SqlStatementKeys :: DELETE_URL_REWRITE ) , SqlStatementKeys :: DELETE_URL_REWRITE_BY_SKU => $ this -> loadStatement ( SqlStatementKeys :: DELETE_URL_REWRITE_BY_SKU ) , SqlStatementKeys :: DELETE_URL_REWRITE_BY_PATH => $ this -> loadStatement ( SqlStatementKeys :: DELETE_URL_REWRITE_BY_PATH ) , SqlStatementKeys :: DELETE_URL_REWRITE_BY_CATEGORY_ID => $ this -> loadStatement ( SqlStatementKeys :: DELETE_URL_REWRITE_BY_CATEGORY_ID ) ) ; }

Return's the array with the SQL statements that has to be prepared.

@return array The SQL statements to be prepared
@see \TechDivision\Import\Actions\Processors\AbstractBaseProcessor::getStatements()

Return s the array with the SQL statements that has to be prepared .


public function createImportAdapter(SubjectConfigurationInterface $subjectConfiguration)
    {

        // load the import adapter configuration
        $importAdapterConfiguration = $subjectConfiguration->getImportAdapter();

        // load the serializer factory instance
        $serializerFactory = $this->container->get($importAdapterConfiguration->getSerializer()->getId());

        // create the instance and pass the import adapter configuration instance
        $importAdapter = $this->container->get(DependencyInjectionKeys::IMPORT_ADAPTER_IMPORT_CSV);
        $importAdapter->init($importAdapterConfiguration, $serializerFactory);

        // return the initialized import adapter instance
        return $importAdapter;
    }

Creates and returns the import adapter for the subject with the passed configuration.

@param \TechDivision\Import\Configuration\SubjectConfigurationInterface $subjectConfiguration The subject configuration

@return \TechDivision\Import\Adapter\ExportAdapterInterface The import adapter instance

Creates and returns the import adapter for the subject with the passed configuration .


protected function prepareCallbacks(SubjectInterface $subject, array $callbacks, $type = null)
    {

        // iterate over the array with callbacks and prepare them
        foreach ($callbacks as $key => $callback) {
            // we have to initialize the type only on the first level
            if ($type == null) {
                $type = $key;
            }

            // query whether or not we've an subarry or not
            if (is_array($callback)) {
                $this->prepareCallbacks($subject, $callback, $type);
            } else {
                $subject->registerCallback($this->container->get($callback), $type);
            }
        }
    }

Prepare the callbacks defined in the system configuration.

@param \TechDivision\Import\Subjects\SubjectInterface $subject   The subject to prepare the callbacks for
@param array                                          $callbacks The array with the callbacks
@param string                                         $type      The actual callback type

@return void

Prepare the callbacks defined in the system configuration .


public function getGlobalData()
    {

        // initialize the array for the global data
        $globalData = array();

        // initialize the global data
        $globalData[RegistryKeys::STORES] = $this->getStores();
        $globalData[RegistryKeys::LINK_TYPES] = $this->getLinkTypes();
        $globalData[RegistryKeys::TAX_CLASSES] = $this->getTaxClasses();
        $globalData[RegistryKeys::IMAGE_TYPES] = $this->getImageTypes();
        $globalData[RegistryKeys::DEFAULT_STORE] = $this->getDefaultStore();
        $globalData[RegistryKeys::STORE_WEBSITES] = $this->getStoreWebsites();
        $globalData[RegistryKeys::LINK_ATTRIBUTES] = $this->getLinkAttributes();
        $globalData[RegistryKeys::ROOT_CATEGORIES] = $this->getRootCategories();
        $globalData[RegistryKeys::CUSTOMER_GROUPS] = $this->getCustomerGroups();
        $globalData[RegistryKeys::CORE_CONFIG_DATA] = $this->getCoreConfigData();
        $globalData[RegistryKeys::ENTITY_TYPES] = $eavEntityTypes = $this->getEavEntityTypes();

        // prepare the attribute sets
        $eavAttributes = array();
        $eavAttributeSets = array();
        $eavAttributeGroups = array();
        foreach ($eavEntityTypes as $eavEntityTypeCode => $eavEntityType) {
            // load the attribute sets for the entity type
            $attributeSets = $this->getEavAttributeSetsByEntityTypeId($entityTypeId = $eavEntityType[MemberNames::ENTITY_TYPE_ID]);
            // append the attribute sets to the array
            $eavAttributeSets[$eavEntityTypeCode] = $attributeSets;

            // iterate over the attribute sets and initialize the attributes
            foreach ($attributeSets as $attributeSet) {
                // load the attribute set name
                $eavAttributeSetName = $attributeSet[MemberNames::ATTRIBUTE_SET_NAME];

                // load the attributes for the attribute set
                $eavAttributes[$eavEntityTypeCode][$eavAttributeSetName] = $this->getEavAttributesByEntityTypeIdAndAttributeSetName(
                    $entityTypeId,
                    $eavAttributeSetName
                );

                // load the attribute group for the attribute set
                $eavAttributeGroups[$eavEntityTypeCode][$eavAttributeSetName] = $this->getEavAttributeGroupsByAttributeSetId(
                    $attributeSet[MemberNames::ATTRIBUTE_SET_ID]
                );
            }
        }

        // prepare the user defined attributes
        $eavUserDefinedAttributes = array();
        foreach ($eavEntityTypes as $eavEntityTypeCode => $eavEntityType) {
            // load the user defined attributes for the entity type
            $eavUserDefinedAttributes[$eavEntityTypeCode] = $this->getEavAttributesByEntityTypeIdAndIsUserDefined(
                $eavEntityType[MemberNames::ENTITY_TYPE_ID]
            );
        }

        // initialize the arrays with the EAV attributes, EAV user defined attributes and attribute sets/groups
        $globalData[RegistryKeys::EAV_ATTRIBUTES] = $eavAttributes;
        $globalData[RegistryKeys::ATTRIBUTE_SETS] = $eavAttributeSets;
        $globalData[RegistryKeys::ATTRIBUTE_GROUPS] = $eavAttributeGroups;
        $globalData[RegistryKeys::EAV_USER_DEFINED_ATTRIBUTES] = $eavUserDefinedAttributes;

        // initialize categories per store view
        $globalData[RegistryKeys::CATEGORIES] = array();
        foreach ($globalData[RegistryKeys::STORES] as $storeView) {
            $storeViewCode = $storeView[MemberNames::CODE];
            $storeViewId = $storeView[MemberNames::STORE_ID];
            $globalData[RegistryKeys::CATEGORIES][$storeViewCode] = $this->categoryAssembler->getCategoriesWithResolvedPathByStoreView($storeViewId);
        }

        // return the array
        return $globalData;
    }

Returns the array with the global data necessary for the
import process.

@return array The array with the global data

Returns the array with the global data necessary for the import process .


public function load($id)
    {

        // try to find the SQL statement with the passed key
        if (isset($this->preparedStatements[$id])) {
            return $this->preparedStatements[$id];
        }

        // throw an exception if NOT available
        throw new \Exception(sprintf('Can\'t find SQL statement with ID %s', $id));
    }

Returns the SQL statement with the passed ID.

@param string $id The ID of the SQL statement to return

@return string The SQL statement
@throws \Exception Is thrown, if the SQL statement with the passed key cannot be found

Returns the SQL statement with the passed ID .


public function createDateConverter(SubjectConfigurationInterface $subject)
    {

        // create a new date converter instance for the subject with the passed configuration
        $dateConverter = $this->container->get($subject->getDateConverter()->getId());
        $dateConverter->setSubjectConfiguration($subject);

        // return the date converter instance
        return $dateConverter;
    }

Creates and returns the date converter instance for the subject with the passed configuration.

@param \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject The subject to create the date converter for

@return \TechDivision\Import\Subjects\I18n\DateConverterInterface The date converter instance

Creates and returns the date converter instance for the subject with the passed configuration .


protected function overrideArtefacts($type, array $artefacts)
    {
        foreach ($artefacts as $key => $artefact) {
            $this->artefacs[$type][$this->getLastEntityId()][$key] = $artefact;
        }
    }

protected function overrideArtefacts ( $ type , array $ artefacts ) { foreach ( $ artefacts as $ key => $ artefact ) { $ this -> artefacs [ $ type ] [ $ this -> getLastEntityId ( ) ] [ $ key ] = $ artefact ; } }

Add the passed product type artefacts to the product with the
last entity ID and overrides existing ones with the same key.

@param string $type      The artefact type, e. g. configurable
@param array  $artefacts The product type artefacts

@return void

Add the passed product type artefacts to the product with the last entity ID and overrides existing ones with the same key .


protected function appendArtefacts($type, array $artefacts)
    {
        foreach ($artefacts as $artefact) {
            $this->artefacs[$type][$this->getLastEntityId()][] = $artefact;
        }
    }

protected function appendArtefacts ( $ type , array $ artefacts ) { foreach ( $ artefacts as $ artefact ) { $ this -> artefacs [ $ type ] [ $ this -> getLastEntityId ( ) ] [ ] = $ artefact ; } }

Append's the passed product type artefacts to the product with the
last entity ID.

@param string $type      The artefact type, e. g. configurable
@param array  $artefacts The product type artefacts

@return void

Append s the passed product type artefacts to the product with the last entity ID .


public function getArtefactsByTypeAndEntityId($type, $entityId)
    {

        // query whether or not, artefacts for the passed params are available
        if (isset($this->artefacs[$type][$entityId])) {
            // load the artefacts
            $artefacts = $this->artefacs[$type][$entityId];

            // unserialize the original data
            array_walk($artefacts, function (&$artefact) {
                if (isset($artefact[ColumnKeys::ORIGINAL_DATA])) {
                    $artefact[ColumnKeys::ORIGINAL_DATA] = unserialize($artefact[ColumnKeys::ORIGINAL_DATA]);
                }
            });

            // return the artefacts
            return $artefacts;
        }

        // throw an exception if not
        throw new \Exception(
            sprintf(
                'Cant\'t load artefacts for type %s and entity ID %d',
                $type,
                $entityId
            )
        );
    }

Return the artefacts for the passed type and entity ID.

@param string $type     The artefact type, e. g. configurable
@param string $entityId The entity ID to return the artefacts for

@return array The array with the artefacts
@throws \Exception Is thrown, if no artefacts are available

Return the artefacts for the passed type and entity ID .


public function newArtefact(array $columns, array $originalColumnNames = array())
    {

        // initialize the original data and the artefact
        $artefact = array();
        $originalData = array();

        // query whether or not, we've original columns
        if (sizeof($originalColumnNames) > 0) {
            // prepare the original column data
            $originalData[ColumnKeys::ORIGINAL_FILENAME] = $this->getFilename();
            $originalData[ColumnKeys::ORIGINAL_LINE_NUMBER] = $this->getLineNumber();
            $originalData[ColumnKeys::ORIGINAL_COLUMN_NAMES] =  $originalColumnNames;

            // add the original column data to the new artefact
            $artefact = array(ColumnKeys::ORIGINAL_DATA => $originalData);
        }

        // merge the columns into the artefact entity and return it
        return array_merge($artefact, $columns);
    }

Create's and return's a new empty artefact entity.

@param array $columns             The array with the column data
@param array $originalColumnNames The array with a mapping from the old to the new column names

@return array The new artefact entity

Create s and return s a new empty artefact entity .


public function export($timestamp, $counter)
    {
        $this->getExportAdapter()->export($this->getArtefacts(), $this->getTargetDir(), $timestamp, $counter);
    }

public function export ( $ timestamp , $ counter ) { $ this -> getExportAdapter ( ) -> export ( $ this -> getArtefacts ( ) , $ this -> getTargetDir ( ) , $ timestamp , $ counter ) ; }

Export's the artefacts to CSV files.

@param integer $timestamp The timestamp part of the original import file
@param string  $counter   The counter part of the origin import file

@return void


public function findAll()
    {

        // query whether or not we've already loaded the value
        if (!isset($this->cache[__METHOD__])) {
            // try to load the link types
            $this->linkTypeStmt->execute();

            // initialize the array for the link types
            $linkTypes = array();

            // load the available link types
            $availableLinkTypes = $this->linkTypeStmt->fetchAll(\PDO::FETCH_ASSOC);

            // prepare the link types => we need the code as key
            foreach ($availableLinkTypes as $linkType) {
                $linkTypes[$linkType[MemberNames::CODE]] = $linkType;
            }

            // append the link types to the cache
            $this->cache[__METHOD__] = $linkTypes;
        }

        // return the link types from the cache
        return $this->cache[__METHOD__];
    }

Return's an array with all available link types with the link type code as key.

@return array The available link types

Return s an array with all available link types with the link type code as key .


public function findAll()
    {

        // initialize the result array
        $result = array();

        // load and the image types from the EAV attribute table
        $this->imageTypesByEntityTypeCodeAndFrontendInputStmt->execute();

        // fetch the image types with the passed parameters
        if ($imageTypes = $this->imageTypesByEntityTypeCodeAndFrontendInputStmt->fetchAll(\PDO::FETCH_ASSOC)) {
            // iterate over the image types found
            foreach ($imageTypes as $imageType) {
                $attributeCode = $imageType[MemberNames::ATTRIBUTE_CODE];
                // map the default image types
                if (isset($this->defaultMappings[$attributeCode])) {
                    $attributeCode = $this->defaultMappings[$attributeCode];
                }

                // add the (mapped) image type
                $result[$attributeCode] = sprintf('%s_label', $attributeCode);
            }
        }

        // return the result
        return $result;
    }

Return's an array with all available image types for the passed entity type code
and frontend input type with the link type code as key.

@return array The available image types

Return s an array with all available image types for the passed entity type code and frontend input type with the link type code as key .


public function convert($date)
    {

        // create a DateTime instance from the passed value
        if ($dateTime = \DateTime::createFromFormat($this->getDateConverterConfiguration()->getSourceDateFormat(), $date)) {
            return $dateTime->format('Y-m-d H:i:s');
        }

        // return NULL, if the passed value is NOT a valid date
        return null;
    }

Converts the passed date into a Magento 2 compatible date format.

@param string $date The date to convert

@return string The converted date

Converts the passed date into a Magento 2 compatible date format .


public function convert($number)
    {

        // initialize the formatter instance with the source locale
        $formatter = \NumberFormatter::create($this->getNumberConverterConfiguration()->getLocale(), \NumberFormatter::DECIMAL);

        // parse, format and return the value
        return $this->getFormatter()->format($formatter->parse($number));
    }

Converts the passed number into a float value.

@param string $number The number to parse

@return float The float value of the number

Converts the passed number into a float value .


public function execute(SubjectConfigurationInterface $subject, array $matches, $serial, $pathname)
    {

        // initialize the subject and import the bunch
        $subjectInstance = $this->subjectFactory->createSubject($subject);

        try {
            // setup the subject instance
            $subjectInstance->setUp($serial);

            // initialize the callbacks/observers
            $this->callbackVisitor->visit($subjectInstance);
            $this->observerVisitor->visit($subjectInstance);

            // finally import the CSV file
            $subjectInstance->import($serial, $pathname);

            // query whether or not, we've to export artefacts
            if ($subjectInstance instanceof ExportableSubjectInterface) {
                $subjectInstance->export(
                    $matches[BunchKeys::FILENAME],
                    $matches[BunchKeys::COUNTER]
                );
            }

            // tear down the subject instance
            $subjectInstance->tearDown($serial);
        } catch (\Exception $e) {
            // query whether or not, we've to export artefacts
            if ($subjectInstance instanceof ExportableSubjectInterface) {
                // tear down the subject instance
                $subjectInstance->tearDown($serial);
            }

            // re-throw the exception
            throw $e;
        }
    }

Executes the passed subject.

@param \TechDivision\Import\Configuration\SubjectConfigurationInterface $subject  The message with the subject information
@param array                                                            $matches  The bunch matches
@param string                                                           $serial   The UUID of the actual import
@param string                                                           $pathname The path to the file to import

@return void


protected function getPatternKeys()
    {

        // load the pattern keys from the configuration
        $patternKeys = $this->getPatternElements();

        // make sure that they are all lowercase
        array_walk($patternKeys, function (&$value) {
            $value = strtolower($value);
        });

        // return the pattern keys
        return $patternKeys;
    }

Returns the elements the filenames consists of, converted to lowercase.

@return array The array with the filename elements

Returns the elements the filenames consists of converted to lowercase .


protected function resolvePatternValues()
    {

        // initialize the array
        $elements = array();

        // load the pattern keys
        $patternKeys = $this->getPatternKeys();

        // prepare the pattern values
        foreach ($patternKeys as $element) {
            $elements[] = sprintf('(?<%s>%s)', $element, $this->resolvePatternValue($element));
        }

        // return the pattern values
        return $elements;
    }

protected
function
resolvePatternValues
(
)
{
// initialize the array
$
elements
=
array
(
)
;
// load the pattern keys
$
patternKeys
=
$
this
->
getPatternKeys
(
)
;
// prepare the pattern values
foreach
(
$
patternKeys
as
$
element
)
{
$
elements
[
]
=
sprintf
(
'(?<%s>%s)'
,
$
element
,
$
this
->
resolvePatternValue
(
$
element
)
)
;
}
// return the pattern values
return
$
elements
;
}

Returns the values to create the regex pattern from.

@return array The array with the pattern values

Returns the values to create the regex pattern from .


protected function resolvePatternValue($element)
    {

        // query whether or not matches has been found OR the counter element has been passed
        if ($this->countMatches() === 0 || BunchKeys::COUNTER === $element) {
            // prepare the method name for the callback to load the pattern value with
            $methodName = sprintf('get%s', ucfirst($element));

            // load the pattern value
            if (in_array($methodName, get_class_methods($this->getFileResolverConfiguration()))) {
                return call_user_func(array($this->getFileResolverConfiguration(), $methodName));
            }

            // stop processing
            return;
        }

        // try to load the pattern value from the matches
        return $this->getMatch($element);
    }

Resolves the pattern value for the given element name.

@param string $element The element name to resolve the pattern value for

@return string|null The resolved pattern value

Resolves the pattern value for the given element name .


protected function preparePattern()
    {
        return sprintf($this->getRegex(), implode($this->getElementSeparator(), $this->resolvePatternValues()), $this->getSuffix());
    }

protected function preparePattern ( ) { return sprintf ( $ this -> getRegex ( ) , implode ( $ this -> getElementSeparator ( ) , $ this -> resolvePatternValues ( ) ) , $ this -> getSuffix ( ) ) ; }

Prepares and returns the pattern for the regex to load the files from the
source directory for the passed subject.

@return string The prepared regex pattern

Prepares and returns the pattern for the regex to load the files from the source directory for the passed subject .


protected function prepareOkFilename(array $parts)
    {
        return sprintf('%s/%s.%s', $this->getSourceDir(), implode($this->getElementSeparator(), $parts), $this->getOkFileSuffix());
    }

protected function prepareOkFilename ( array $ parts ) { return sprintf ( '%s/%s.%s' , $ this -> getSourceDir ( ) , implode ( $ this -> getElementSeparator ( ) , $ parts ) , $ this -> getOkFileSuffix ( ) ) ; }

Prepares and returns an OK filename from the passed parts.

@param array $parts The parts to concatenate the OK filename from

@return string The OK filename

Prepares and returns an OK filename from the passed parts .


protected function isEqualFilename($filename1, $filename2)
    {
        return $this->stripSuffix($filename1, $this->getSuffix()) === $this->stripSuffix($filename2, $this->getOkFileSuffix());
    }

protected function isEqualFilename ( $ filename1 , $ filename2 ) { return $ this -> stripSuffix ( $ filename1 , $ this -> getSuffix ( ) ) === $ this -> stripSuffix ( $ filename2 , $ this -> getOkFileSuffix ( ) ) ; }

Query whether or not the basename, without suffix, of the passed filenames are equal.

@param string $filename1 The first filename to compare
@param string $filename2 The second filename to compare

@return boolean TRUE if the passed files basename are equal, else FALSE

Query whether or not the basename without suffix of the passed filenames are equal .


protected function getOkFilenames()
    {

        // initialize the array for the available okFilenames
        $okFilenames = array();

        // prepare the OK filenames based on the found CSV file information
        for ($i = 1; $i <= sizeof($patternKeys = $this->getPatternKeys()); $i++) {
            // intialize the array for the parts of the names (prefix, filename + counter)
            $parts = array();
            // load the parts from the matches
            for ($z = 0; $z < $i; $z++) {
                // append the part
                $parts[] = $this->getMatch($patternKeys[$z]);
            }

            // query whether or not, the OK file exists, if yes append it
            if (file_exists($okFilename = $this->prepareOkFilename($parts))) {
                $okFilenames[] = $okFilename;
            }
        }

        // prepare and return the pattern for the OK file
        return $okFilenames;
    }

Return's an array with the names of the expected OK files for the actual subject.

@return array The array with the expected OK filenames

Return s an array with the names of the expected OK files for the actual subject .


public function shouldBeHandled($filename)
    {

        // initialize the array with the matches
        $matches = array();

        // update the matches, if the pattern matches
        if ($result = preg_match($this->preparePattern(), $filename, $matches)) {
            foreach ($matches as $name => $match) {
                $this->addMatch($name, $match);
            }
        }

        // stop processing, if the filename doesn't match
        return (boolean) $result;
    }

Queries whether or not, the passed filename should be handled by the subject.

@param string $filename The filename to query for

@return boolean TRUE if the file should be handled, else FALSE

Queries whether or not the passed filename should be handled by the subject .


public function cleanUpOkFile($filename)
    {

        // query whether or not the subject needs an OK file, if yes remove the filename from the file
        if ($this->getSubjectConfiguration()->isOkFileNeeded() === false) {
            return;
        }

        try {
            // try to load the expected OK filenames
            if (sizeof($okFilenames = $this->getOkFilenames()) === 0) {
                throw new MissingOkFileException(sprintf('Can\'t find a OK filename for file %s', $filename));
            }

            // iterate over the found OK filenames (should usually be only one, but could be more)
            foreach ($okFilenames as $okFilename) {
                // if the OK filename matches the CSV filename AND the OK file is empty
                if ($this->isEqualFilename($filename, $okFilename) && filesize($okFilename) === 0) {
                    unlink($okFilename);
                    return;
                }

                // else, remove the CSV filename from the OK file
                $this->removeLineFromFile(basename($filename), $fh = fopen($okFilename, 'r+'));
                fclose($fh);

                // if the OK file is empty, delete the file
                if (filesize($okFilename) === 0) {
                    unlink($okFilename);
                }

                // return immediately
                return;
            }

            // throw an exception if either no OK file has been found,
            // or the CSV file is not in one of the OK files
            throw new \Exception(
                sprintf(
                    'Can\'t found filename %s in one of the expected OK files: %s',
                    $filename,
                    implode(', ', $okFilenames)
                )
            );
        } catch (LineNotFoundException $lne) {
            // wrap and re-throw the exception
            throw new \Exception(
                sprintf(
                    'Can\'t remove filename %s from OK file: %s',
                    $filename,
                    $okFilename
                ),
                null,
                $lne
            );
        }
    }

Query whether or not, the passed CSV filename is in the OK file. If the filename was found,
the OK file will be cleaned-up.

@param string $filename The filename to be cleaned-up

@return void
@throws \Exception Is thrown, if the passed filename is NOT in the OK file or the OK can not be cleaned-up

Query whether or not the passed CSV filename is in the OK file . If the filename was found the OK file will be cleaned - up .


public function findAll()
    {

        // initialize the array with the available tax classes
        $taxClasses = array();

        // execute the prepared statement
        $this->taxClassesStmt->execute();

        // load the available tax classes
        $availableTaxClasses = $this->taxClassesStmt->fetchAll();

        // fetch the tax classes and assemble them as array with the class name as key
        foreach ($availableTaxClasses as $taxClass) {
            $taxClasses[$taxClass[MemberNames::CLASS_NAME]] = $taxClass;
        }

        // return the array with the tax classes
        return $taxClasses;
    }

Return's an array with the available tax classes and their
class names as keys.

@return array The array with all available tax classes

Return s an array with the available tax classes and their class names as keys .


public function warm()
    {

        // load the available EAV attribute option values
        $eavAttributeOptionValues = $this->repository->findAll();

        // prepare the caches for the statements
        foreach ($eavAttributeOptionValues as $eavAttributeOptionValue) {
            // prepare the cache key and add the option value to the cache
            $cacheKey1 = $this->repository->cacheKey(
                SqlStatementKeys::EAV_ATTRIBUTE_OPTION_VALUE_BY_OPTION_ID_AND_STORE_ID,
                array(
                    MemberNames::STORE_ID  => $eavAttributeOptionValue[MemberNames::STORE_ID],
                    MemberNames::OPTION_ID => $eavAttributeOptionValue[MemberNames::OPTION_ID]
                )
            );

            // prepare the cache key and add the option value to the cache
            $cacheKey2 = $this->repository->cacheKey(
                SqlStatementKeys::EAV_ATTRIBUTE_OPTION_VALUE_BY_ATTRIBUTE_CODE_AND_STORE_ID_AND_VALUE,
                array(
                    MemberNames::ATTRIBUTE_CODE => $eavAttributeOptionValue[MemberNames::ATTRIBUTE_CODE],
                    MemberNames::STORE_ID       => $eavAttributeOptionValue[MemberNames::STORE_ID],
                    MemberNames::VALUE          => $eavAttributeOptionValue[MemberNames::VALUE]
                )
            );

            // add the EAV attribute option value to the cache
            $this->repository->toCache(
                $eavAttributeOptionValue[MemberNames::VALUE_ID],
                $eavAttributeOptionValue,
                array(
                    $cacheKey1 => $eavAttributeOptionValue[MemberNames::VALUE_ID],
                    $cacheKey2 => $eavAttributeOptionValue[MemberNames::VALUE_ID]
                )
            );
        }
    }

Warms the cache for the passed repository.

@return void

Warms the cache for the passed repository .


public function findAll()
    {

        // initialize the array with the available store websites
        $storeWebsites = array();

        // execute the prepared statement
        $this->storeWebsitesStmt->execute();

        // load the available store websites
        $availableStoreWebsites = $this->storeWebsitesStmt->fetchAll();

        // fetch the store websites and assemble them as array with the codes as key
        foreach ($availableStoreWebsites as $storeWebsite) {
            $storeWebsites[$storeWebsite[MemberNames::CODE]] = $storeWebsite;
        }

        // return the array with the store websites
        return $storeWebsites;
    }

Return's an array with the available store websites and their
code as keys.

@return array The array with all available store websites

Return s an array with the available store websites and their code as keys .


public function findAll()
    {

        // initialize the array with the available stores
        $stores = array();

        // execute the prepared statement
        $this->storesStmt->execute();

        // load the available stores
        $availableStores = $this->storesStmt->fetchAll();

        // fetch the stores and assemble them as array with the store code as key
        foreach ($availableStores as $store) {
            $stores[$store[MemberNames::CODE]] = $store;
        }

        // return the array with the stores
        return $stores;
    }

Return's an array with the available stores and their
store codes as keys.

@return array The array with all available stores

Return s an array with the available stores and their store codes as keys .


public function findAllByEntityIds(array $entityIds)
    {

        // prepare the cache key
        $vals = implode(',', $entityIds);
        $sql = str_replace('?', $vals, $this->loadStatement(SqlStatementKeys::CATEGORY_VARCHARS_BY_ENTITY_IDS));

        // load the categories with the passed values and return them
        if ($stmt = $this->getConnection()->query($sql)) {
            return $stmt->fetchAll();
        }
    }

Returns the category varchar values for the categories with
the passed with the passed entity IDs.

@param array $entityIds The array with the category IDs

@return mixed The category varchar values

Returns the category varchar values for the categories with the passed with the passed entity IDs .


public function findByEntityId($entityId)
    {

        // prepare the cache key
        $sql = str_replace('?', $entityId, $this->loadStatement(SqlStatementKeys::CATEGORY_VARCHARS_BY_ENTITY_IDS));

        // load the categories with the passed values and return them
        if ($stmt = $this->getConnection()->query($sql)) {
            return $stmt->fetch();
        }
    }

Returns the category varchar values for the categories with
the passed with the passed entity ID.

@param int $entityId The category ID

@return array The category varchar values

Returns the category varchar values for the categories with the passed with the passed entity ID .


public function findAll()
    {

        // initialize the array for the customer groups
        $customerGroups = [];

        // execute the prepared statement
        $this->customerGroupsStmt->execute();

        // load the available customer groups
        $availableCustomerGroups = $this->customerGroupsStmt->fetchAll();

        // fetch the customer groups and assemble them as array with the codes as key
        foreach ($availableCustomerGroups as $customerGroup) {
            $customerGroups[$customerGroup[MemberNames::CUSTOMER_GROUP_CODE]] = $customerGroup;
        }

        // return the customer groups
        return $customerGroups;
    }

Returns an array with the available customer groups and their code as keys.

@return array The array with the customer groups

Returns an array with the available customer groups and their code as keys .


public function getPrimaryKeyMemberName()
    {

        // make sure the edition name is in upper cases
        $editionName = strtoupper($this->configuration->getMagentoEdition());

        // return the primary key member name for the actual edition
        if (isset($this->editionPrimaryKeyMemberNameMappings[$editionName])) {
            return $this->editionPrimaryKeyMemberNameMappings[$editionName];
        }

        // throw an exception if the edition is NOT supported/available
        throw new \Exception(sprintf('Found not supported/available Magento edition name "%s"', $editionName));
    }

Returns the primary key member name for the actual Magento edition.

@return string The primary key member name
@throws \Exception Is thrown if the edition is not supported/available

Returns the primary key member name for the actual Magento edition .


protected function clearRow()
    {

        // query whether or not the column keys has been initialized
        if ($this->cleanUpEmptyColumnKeys === null) {
            // initialize the array with the column keys that has to be cleaned-up
            $this->cleanUpEmptyColumnKeys = array();

            // query whether or not column names that has to be cleaned up have been configured
            if ($this->getSubject()->getConfiguration()->hasParam(ConfigurationKeys::CLEAN_UP_EMPTY_COLUMNS)) {
                // if yes, load the column names
                $cleanUpEmptyColumns = $this->getSubject()->getCleanUpColumns();

                // translate the column names into column keys
                foreach ($cleanUpEmptyColumns as $cleanUpEmptyColumn) {
                    if ($this->hasHeader($cleanUpEmptyColumn)) {
                        $this->cleanUpEmptyColumnKeys[] = $this->getHeader($cleanUpEmptyColumn);
                    }
                }
            }
        }

        // remove all the empty values from the row, expected the columns has to be cleaned-up
        return array_filter(
            $this->row,
            function ($value, $key) {
                return ($value !== null && $value !== '') || in_array($key, $this->cleanUpEmptyColumnKeys);
            },
            ARRAY_FILTER_USE_BOTH
        );
    }

Remove all the empty values from the row and return the cleared row.

@return array The cleared row

Remove all the empty values from the row and return the cleared row .


public static function blade($view, $data = array(), $viewPath = EVENTMANAGERINTEGRATION_VIEW_PATH)
    {
        if (!file_exists(EVENTMANAGERINTEGRATION_CACHE_DIR)) {
            mkdir(EVENTMANAGERINTEGRATION_CACHE_DIR, 0777, true);
        }

        $blade = new Blade($viewPath, EVENTMANAGERINTEGRATION_CACHE_DIR);
        return $blade->view()->make($view, $data)->render();
    }

public static function blade ( $ view , $ data = array ( ) , $ viewPath = EVENTMANAGERINTEGRATION_VIEW_PATH ) { if ( ! file_exists ( EVENTMANAGERINTEGRATION_CACHE_DIR ) ) { mkdir ( EVENTMANAGERINTEGRATION_CACHE_DIR , 0777 , true ) ; } $ blade = new Blade ( $ viewPath , EVENTMANAGERINTEGRATION_CACHE_DIR ) ; return $ blade -> view ( ) -> make ( $ view , $ data ) -> render ( ) ; }

Return markup from a Blade template
@param  string $view     View name
@param  array  $data     View data
@param  string $viewPath Path to the blade views
@return string           The markup


public function registerRestRoutes()
    {
        register_rest_route(
            'wp/v2',
            '/'.$this->postType.'/'.'module',
            array(
                'methods' => \WP_REST_Server::READABLE,
                'callback' => array($this, 'getEvents'),
                'args' => $this->getCollectionParams(),
                'permission_callback' => array($this, 'validateNonce'),
            )
        );
    }

public function registerRestRoutes ( ) { register_rest_route ( 'wp/v2' , '/' . $ this -> postType . '/' . 'module' , array ( 'methods' => \ WP_REST_Server :: READABLE , 'callback' => array ( $ this , 'getEvents' ) , 'args' => $ this -> getCollectionParams ( ) , 'permission_callback' => array ( $ this , 'validateNonce' ) , ) ) ; }

Registers all rest routes for events
@return void


public function getCollectionParams()
    {
        return array(
            'page' => array(
                'description' => 'Current page of the collection.',
                'type' => 'integer',
                'default' => 1,
                'sanitize_callback' => 'absint',
            ),
            'per_page' => array(
                'description' => 'Maximum number of items to be returned in result collection.',
                'type' => 'integer',
                'default' => 10,
                'sanitize_callback' => array($this, 'sanitizePerPage'),
            ),
            'start_date' => array(
                'description' => 'Get events from this date',
                'type' => 'string',
                'default' => date('Y-m-d H:i:s', strtotime("today midnight")),
                'sanitize_callback' => array($this, 'sanitizeDate'),
            ),
            'end_date' => array(
                'description' => 'Get events to this date',
                'type' => 'string',
                'default' => date('Y-m-d H:i:s', strtotime("today midnight")),
                'sanitize_callback' => array($this, 'sanitizeEndDate'),
            ),
            'categories' => array(
                'description' => 'Filter by categories',
                'type' => 'object',
                'default' => null,
            ),
            'tags' => array(
                'description' => 'Filter by tags',
                'type' => 'object',
                'default' => null,
            ),
            'groups' => array(
                'description' => 'Filter by groups',
                'type' => 'object',
                'default' => null,
            ),
            'lat' => array(
                'description' => 'Filter by coordinates',
                'type' => 'string',
                'default' => null,
            ),
            'lng' => array(
                'description' => 'Filter by coordinates',
                'type' => 'string',
                'default' => null,
            ),
            'distance' => array(
                'description' => 'Distance (km) radius from coordinates',
                'type' => 'float',
                'default' => null,
            ),
            'module_id' => array(
                'description' => 'The module ID',
                'type' => 'integer',
                'default' => 0,
                'sanitize_callback' => 'absint',
            ),
            'search_string' => array(
                'description' => 'Filter by search string',
                'type' => 'string',
                'default' => '',
                'sanitize_callback' => 'sanitize_text_field',
            ),
            'age_group' => array(
                'description' => 'Filter by age group.',
                'type' => 'object',
                'default' => null,
            ),
            'lang' => array(
                'description' => 'Filter by language.',
                'type' => 'string',
                'default' => null,
            ),
        );
    }

Get the query params for collections
@return array


public function sanitizeEndDate($data)
    {
        $data = strtotime($data);

        if ($data == false) {
            $data = strtotime('today midnight');
        }

        $data = strtotime('+1 day', $data) - 1;

        return date('Y-m-d H:i:s', $data);
    }

public
function
sanitizeEndDate
(
$
data
)
{
$
data
=
strtotime
(
$
data
)
;
if
(
$
data
==
false
)
{
$
data
=
strtotime
(
'today midnight'
)
;
}
$
data
=
strtotime
(
'+1 day'
,
$
data
)
1
;
return
date
(
'Y-m-d H:i:s'
,
$
data
)
;
}

Sanitize end date. Add 1 day to include events occurring on end date
@param $data
@return int

Sanitize end date . Add 1 day to include events occurring on end date


public function getEvents($request)
    {
        // Get params
        $params = $request->get_params();

        // Set display limit to -1 to get all events
        $params['display_limit'] = -1;

        // Save coordinates to location array
        if (!empty($params['lat']) && !empty($params['lng'])) {
            $params['location'] = array(
                'lat' => $params['lat'],
                'lng' => $params['lng'],
            );
        }

        // Get events
        $events = \EventManagerIntegration\Helper\QueryEvents::getEventsByInterval($params, 1);
        // Return error if result is empty
        if (empty($events)) {
            return new \WP_REST_Response(
                array(
                    'message' => __('No events could be found.', 'event-integration'),
                    'state' => 'empty_result',
                ),
                404
            );
        }

        // Set total items & pages count
        $total = count($events);
        $totalPages = 1;

        // If per page param is not unlimited, get chunk of paged items
        if ($params['per_page'] !== -1) {
            // Calculate total pages
            $totalPages = ceil($total / $params['per_page']);
            $offset = ($params['page'] - 1) * $params['per_page'];
            $offset = $offset > 0 ? $offset : 0;
            $events = array_slice($events, $offset, $params['per_page']);
        }

        // Sanitize and add meta data to items list
        $events = $this->mapEventModuleData($params['module_id'], $events);

        $response = rest_ensure_response($events);
        // Set headers with total counts
        $response->header('X-WP-Total', $total);
        $response->header('X-WP-TotalPages', $totalPages);

        return $response;
    }

Get all events between two dates
@param object $request Object containing request details
@return array|\WP_REST_Response


public function mapEventModuleData($moduleId, $events)
    {
        $data = get_fields($moduleId);

        $template = $data['mod_event_display'] ?? 'list';

        $class = '\EventManagerIntegration\Module\Event\TemplateController\\'.ucwords($template).'Template';

        if (class_exists($class)) {
            $controller = new $class(array(), array(), $data);
            if (is_array($data) && isset($controller->data) && is_array($controller->data)) {
                $data = array_merge($data, $controller->data);
            }
        }

        foreach ($events as &$event) {
            // Set permalink url with date parameter
            $event->permalink = esc_url(
                add_query_arg('date', preg_replace('/\D/', '', $event->start_date), get_permalink($event->ID))
            );

            // Format occasion date
            $event->occasion = \EventManagerIntegration\App::formatEventDate($event->start_date, $event->end_date);

            // Set location
            $location = get_post_meta($event->ID, 'location', true);
            $event->location = !empty($location['title']) ? $location['title'] : null;

            // Get image url
            switch ($template) {
                case 'index':
                    if (function_exists('municipio_get_thumbnail_source') && municipio_get_thumbnail_source(
                            $event->ID,
                            array($data['imageDimensions']['width'], $data['imageDimensions']['height']),
                            $data['imageRatio']
                        )) {
                        $event->image_url = municipio_get_thumbnail_source(
                            $event->ID,
                            array($data['imageDimensions']['width'], $data['imageDimensions']['height']),
                            $data['imageRatio']
                        );
                    } elseif (!empty($data['mod_event_def_image'])) {
                        $src = wp_get_attachment_image_src(
                            $data['mod_event_def_image']['ID'],
                            municipio_to_aspect_ratio(
                                $data['imageRatio'],
                                array($data['imageDimensions']['width'], $data['imageDimensions']['height'])
                            )
                        );

                        $event->image_url = $src[0] ?? null;
                    }

                    break;
                default:
                    if (function_exists('municipio_get_thumbnail_source') && municipio_get_thumbnail_source(
                            $event->ID
                        )) {
                        $event->image_url = municipio_get_thumbnail_source($event->ID);
                    } elseif (!empty($data['mod_event_def_image'])) {
                        $src = wp_get_attachment_image_src(
                            $data['mod_event_def_image']['ID']
                        );

                        $event->image_url = $src[0] ?? null;
                    }
            }

        }

        return $events;
    }

Sanitize and adds data to event list
@param int   $moduleId The module ID
@param array $events   List of events
@return array


public static function defineCategoryTranslations()
    {
        // Bail if translation plugin is not active
        if (!is_plugin_active('polylang-pro/polylang.php') || empty($apiUrl = get_field('event_api_url', 'option'))) {
            return;
        }

        // Build request URL
        $apiUrl = rtrim($apiUrl, '/').'/event_categories?per_page=100';

        // Get categories from Event Manager API
        $result = \EventManagerIntegration\Parser::requestApi($apiUrl);

        if (!$result || is_wp_error($result) || !is_array($result)) {
            return;
        }

        // Lowercase term names
        $result = array_map(
            function ($category) {
                $category['name'] = strtolower($category['name']);

                return $category;
            },
            $result
        );

        // Get all local categories
        $categories = get_terms(
            array(
                'taxonomy' => 'event_categories',
                'hide_empty' => false,
                'lang' => '',
            )
        );

        // Collect list of matched new and original term ID
        $categoryIds = array();

        // Collect term IDs and set lang + translations to categories array
        foreach ($categories as &$category) {
            $category->lang = '';
            $category->translations = array();
            // See if the term exists in both(local and external API) lists
            if (false !== $key = array_search(strtolower($category->name), array_column($result, 'name'))) {
                $categoryIds[$result[$key]['id']] = $category->term_id;
                $category->lang = $result[$key]['lang'] ?? '';
                $category->translations = $result[$key]['translations'] ?? array();
            }
        }

        // Save term lang and define its translations
        foreach ($categories as $category) {
            // Save term lang
            if (!empty($category->lang)) {
                pll_set_term_language($category->term_id, $category->lang);
            }
            // Define translations
            if (!empty($category->translations)) {
                // Replace the original IDs from translations array with the local terms IDs
                $translations =
                    array_filter(
                        array_map(
                            function ($lang) use ($categoryIds) {
                                return array_key_exists($lang, $categoryIds) ? $categoryIds[$lang] : false;
                            },
                            $category->translations
                        )
                    );

                if (empty($translations)) {
                    continue;
                }
                // Save translations
                pll_save_term_translations($translations);
            }
        }

        return;
    }

Set category languages and define translations


public function beforeSave()
    {
        $this->post_title = strip_tags(html_entity_decode($this->post_title));
        $this->post_content = html_entity_decode($this->post_content);
    }

public function beforeSave ( ) { $ this -> post_title = strip_tags ( html_entity_decode ( $ this -> post_title ) ) ; $ this -> post_content = html_entity_decode ( $ this -> post_content ) ; }


public function afterSave()
    {
        $this->saveOccasions();
        $this->saveCategories();
        $this->saveGroups();
        $this->saveTags();
        $this->saveLocation();
        $this->saveAddLocations();
        $this->saveLanguage();

        if (!empty($this->gallery)) {
            foreach ($this->gallery as $key => $image) {
                $this->setFeaturedImageFromUrl($image['url'], false);
            }
        }

        return true;
    }

public function afterSave ( ) { $ this -> saveOccasions ( ) ; $ this -> saveCategories ( ) ; $ this -> saveGroups ( ) ; $ this -> saveTags ( ) ; $ this -> saveLocation ( ) ; $ this -> saveAddLocations ( ) ; $ this -> saveLanguage ( ) ; if ( ! empty ( $ this -> gallery ) ) { foreach ( $ this -> gallery as $ key => $ image ) { $ this -> setFeaturedImageFromUrl ( $ image [ 'url' ] , false ) ; } } return true ; }

Do after save
@return bool Used if post got removed or not


public function saveLocation()
    {
        if ($this->location != null) {
            if (!empty($this->location['parent']) && $this->location['parent']['id'] > 0) {
                $this->location['title'] = $this->location['parent']['title'].', '.$this->location['title'];
            }

            if (!empty($location['latitude']) && !empty($location['longitude'])) {
                update_post_meta($this->ID, 'latitude', $location['latitude']);
                update_post_meta($this->ID, 'longitude', $location['longitude']);
            }
            update_post_meta($this->ID, 'location', $this->location);
        }
    }

public
function
saveLocation
(
)
{
if
(
$
this
->
location
!=
)
{
if
(
!
empty
(
$
this
->
location
[
'parent'
]
)
&&
$
this
->
location
[
'parent'
]
[
'id'
]
>
0
)
{
$
this
->
location
[
'title'
]
=
$
this
->
location
[
'parent'
]
[
'title'
]
.
', '
.
$
this
->
location
[
'title'
]
;
}
if
(
!
empty
(
$
location
[
'latitude'
]
)
&&
!
empty
(
$
location
[
'longitude'
]
)
)
{
update_post_meta
(
$
this
->
ID
,
'latitude'
,
$
location
[
'latitude'
]
)
;
update_post_meta
(
$
this
->
ID
,
'longitude'
,
$
location
[
'longitude'
]
)
;
}
update_post_meta
(
$
this
->
ID
,
'location'
,
$
this
->
location
)
;
}
}

Saves location as meta data
@return void


public function saveAddLocations()
    {
        if (is_array($this->additional_locations) && !empty($this->additional_locations)) {
            foreach ($this->additional_locations as &$location) {
                if (!empty($location['parent']) && $location['parent']['id'] > 0) {
                    $location['title'] = $location['parent']['title'].', '.$location['title'];
                }
            }
            update_post_meta($this->ID, 'additional_locations', $this->additional_locations);
        }
    }

public
function
saveAddLocations
(
)
{
if
(
is_array
(
$
this
->
additional_locations
)
&&
!
empty
(
$
this
->
additional_locations
)
)
{
foreach
(
$
this
->
additional_locations
as
&
$
location
)
{
if
(
!
empty
(
$
location
[
'parent'
]
)
&&
$
location
[
'parent'
]
[
'id'
]
>
0
)
{
$
location
[
'title'
]
=
$
location
[
'parent'
]
[
'title'
]
.
', '
.
$
location
[
'title'
]
;
}
}
update_post_meta
(
$
this
->
ID
,
'additional_locations'
,
$
this
->
additional_locations
)
;
}
}

Saves additional locations as meta data
@return void


public function saveCategories()
    {
        if (empty($this->categories)) {
            $terms = wp_get_post_terms($this->ID, 'event_categories', array('fields' => 'all'));
            if (!empty($terms)) {
                foreach ($terms as $term) {
                    wp_remove_object_terms($this->ID, $term->term_id, 'event_categories');
                }
                delete_post_meta($this->ID, 'categories');
            }
        } else {
            wp_set_object_terms($this->ID, $this->categories, 'event_categories', false);
        }
    }

public function saveCategories ( ) { if ( empty ( $ this -> categories ) ) { $ terms = wp_get_post_terms ( $ this -> ID , 'event_categories' , array ( 'fields' => 'all' ) ) ; if ( ! empty ( $ terms ) ) { foreach ( $ terms as $ term ) { wp_remove_object_terms ( $ this -> ID , $ term -> term_id , 'event_categories' ) ; } delete_post_meta ( $ this -> ID , 'categories' ) ; } } else { wp_set_object_terms ( $ this -> ID , $ this -> categories , 'event_categories' , false ) ; } }

Saves categories as taxonomy terms
@return void


public function saveGroups()
    {
        // Save group names as new array
        $event_groups = array();
        if (!empty($this->groups) && is_array($this->groups)) {
            foreach ($this->groups as $group) {
                $event_groups[] .= $group['name'];
            }
        }
        wp_set_object_terms($this->ID, $event_groups, 'event_groups', false);
    }

public
function
saveGroups
(
)
{
// Save group names as new array
$
event_groups
=
array
(
)
;
if
(
!
empty
(
$
this
->
groups
)
&&
is_array
(
$
this
->
groups
)
)
{
foreach
(
$
this
->
groups
as
$
group
)
{
$
event_groups
[
]
.=
$
group
[
'name'
]
;
}
}
wp_set_object_terms
(
$
this
->
ID
,
$
event_groups
,
'event_groups'
,
false
)
;
}

Saves groups as taxonomy terms
@return void


public function saveTags()
    {
        if (empty($this->tags)) {
            $terms = wp_get_post_terms($this->ID, 'event_tags', array('fields' => 'all'));
            if (!empty($terms)) {
                foreach ($terms as $term) {
                    wp_remove_object_terms($this->ID, $term->term_id, 'event_tags');
                }
                delete_post_meta($this->ID, 'tags');
            }
        } else {
            wp_set_object_terms($this->ID, $this->tags, 'event_tags', false);
        }
    }

public function saveTags ( ) { if ( empty ( $ this -> tags ) ) { $ terms = wp_get_post_terms ( $ this -> ID , 'event_tags' , array ( 'fields' => 'all' ) ) ; if ( ! empty ( $ terms ) ) { foreach ( $ terms as $ term ) { wp_remove_object_terms ( $ this -> ID , $ term -> term_id , 'event_tags' ) ; } delete_post_meta ( $ this -> ID , 'tags' ) ; } } else { wp_set_object_terms ( $ this -> ID , $ this -> tags , 'event_tags' , false ) ; } }

Saves tags as taxonomy terms
@return void


public function saveOccasions()
    {
        global $wpdb;

        // Delete all occasions related to the event
        $db_table = $wpdb->prefix."integrate_occasions";
        $wpdb->delete($db_table, array('event_id' => $this->ID), array('%d'));

        // Remove post if occasions is missing
        if ($this->occasions_complete == null || empty($this->occasions_complete)) {
            wp_delete_post($this->ID, true);

            return false;
        }

        // Loop through occasions for the event
        foreach ($this->occasions_complete as $o) {
            $start_date = !empty($o['start_date']) ? $o['start_date'] : null;
            $end_date = !empty($o['end_date']) ? $o['end_date'] : null;
            $door_time = !empty($o['door_time']) ? $o['door_time'] : null;
            $status = !empty($o['status']) ? $o['status'] : null;
            $occ_exeption_information = !empty($o['occ_exeption_information']) ? $o['occ_exeption_information'] : null;
            $content_mode = !empty($o['content_mode']) ? $o['content_mode'] : null;
            $content = !empty($o['content']) ? $o['content'] : null;

            $wpdb->insert(
                $db_table,
                array(
                    'event_id' => $this->ID,
                    'start_date' => $start_date,
                    'end_date' => $end_date,
                    'door_time' => $door_time,
                    'status' => $status,
                    'exception_information' => $occ_exeption_information,
                    'content_mode' => $content_mode,
                    'content' => ($content),
                )
            );
        }

        return true;
    }

Save event occasions to integrate_occasions table
@return boolean true if one or more occasions was saved, false if not.


public function saveLanguage()
    {
        // Bail if Polylang is not active
        if (!is_plugin_active('polylang-pro/polylang.php')) {
            return;
        }

        // Apply language to the event
        if (!empty($this->lang)) {
            pll_set_post_language($this->ID, $this->lang);
        }

        // Define which events are translations of each other
        if (!empty($this->translations)) {
            $translations = $this->translations;
            // Get locally installed languages
            $localLangs = pll_languages_list();
            // Remove all languages that don't exist locally
            $translations = array_filter(
                $translations,
                function ($translation) use ($localLangs) {
                    return in_array($translation, $localLangs);
                },
                ARRAY_FILTER_USE_KEY
            );

            // Replace the old IDs with new events IDs
            foreach ($translations as $key => &$id) {
                $id = $this->getEventByOriginalId($id);
                if (!$id) {
                    // Remove if event cant't be found
                    unset($translations[$key]);
                }
            }
            // Define event translations
            pll_save_post_translations($translations);
        }
    }

Apply language and translations to the event.
Compatible with the plugin 'Polylang'

Apply language and translations to the event . Compatible with the plugin Polylang


public function getEventByOriginalId($id)
    {
        $args = array(
            'meta_query' => array(
                array(
                    'key' => '_event_manager_id',
                    'value' => $id,
                ),
            ),
            'post_type' => $this->post_type,
            'posts_per_page' => '1',
        );

        $events = get_posts($args);

        if (is_wp_error($events) || !isset($events[0]->ID)) {
            return false;
        }

        return $events[0]->ID;
    }

public function getEventByOriginalId ( $ id ) { $ args = array ( 'meta_query' => array ( array ( 'key' => '_event_manager_id' , 'value' => $ id , ) , ) , 'post_type' => $ this -> post_type , 'posts_per_page' => '1' , ) ; $ events = get_posts ( $ args ) ; if ( is_wp_error ( $ events ) || ! isset ( $ events [ 0 ] -> ID ) ) { return false ; } return $ events [ 0 ] -> ID ; }

Find an event by it's original id
@param int $id Event ID
@return Int|bool


public function checkFilters($cat_filter, $tag_filter): bool
    {
        $tax_filter = (empty(get_field('event_filter_cat', 'options')) && empty(
            get_field(
                'event_filter_tag',
                'options'
            )
            )) ? true : false;

        // Check category filters
        if (!empty(get_field('event_filter_cat', 'options'))) {
            $tax_filter = $cat_filter;
        }
        // Check tag filters
        if (!$tax_filter && !empty(get_field('event_filter_tag', 'options'))) {
            $tax_filter = $tag_filter;
        }

        return $tax_filter;
    }

public
function
checkFilters
(
$
cat_filter
,
$
tag_filter
)
:
bool
{
$
tax_filter
=
(
empty
(
get_field
(
'event_filter_cat'
,
'options'
)
)
&&
empty
(
get_field
(
'event_filter_tag'
,
'options'
)
)
)
true
:
false
;
// Check category filters
if
(
!
empty
(
get_field
(
'event_filter_cat'
,
'options'
)
)
)
{
$
tax_filter
=
$
cat_filter
;
}
// Check tag filters
if
(
!
$
tax_filter
&&
!
empty
(
get_field
(
'event_filter_tag'
,
'options'
)
)
)
{
$
tax_filter
=
$
tag_filter
;
}
return
$
tax_filter
;
}

Check if the event passes one of the taxonomy filters
@param  bool $cat_filter Bool, equals true if event passed category filter
@param  bool $tag_filter Bool, equals true if event passed tag filter
@return bool


public function removeExpiredOccasions()
    {
        global $wpdb;
        $date_limit = strtotime("midnight now") - 1;
        // Get all occasions from database
        $db_table = $wpdb->prefix."integrate_occasions";
        $occasions = $wpdb->get_results("SELECT * FROM $db_table ORDER BY start_date DESC", ARRAY_A);

        if (count($occasions) == 0) {
            return;
        }

        foreach ($occasions as $o) {
            // Delete the occasion if expired
            if (strtotime($o['end_date']) < $date_limit) {
                $id = $o['ID'];
                $wpdb->delete($db_table, array('ID' => $id));
            }
        }

        return;
    }

Remove expired occasions from databse
@return void


public function removeDeletedEvents($ids)
    {
        global $wpdb;
        $table = $wpdb->prefix . "integrate_occasions";
        // Get all locally stored events
        $localEvents = $wpdb->get_results("SELECT event_id FROM {$table} GROUP BY event_id", ARRAY_N);
        $localEvents = array_map(function($id) {
            return $id[0];
        }, $localEvents);
        // Collect local IDs of the API events
        $apiEvents = array_map(function($id) {
            $post = get_posts(array(
                'post_type' => 'event',
                'post_status' => array('publish', 'draft'),
                'meta_key' => '_event_manager_id',
                'meta_value' => $id,
                'posts_per_page' => 1
            ));
            return $post[0]->ID ?? null;
        }, array_unique($ids));
        $apiEvents = array_filter($apiEvents);
        // Collect events that is stored locally but is missing in the API
        $diffEvents = array_diff($localEvents, $apiEvents);
        // Loop through the diff and delete its occasions
        if (!empty($diffEvents)) {
            foreach ($diffEvents as $event) {
                $wpdb->delete($table, array('event_id' => $event));
            }
        }
    }

Remove events that has been deleted from API
@param $ids


public function removeExpiredEvents()
    {
        global $wpdb;
        $post_type = 'event';
        // Get all events from databse
        $query = "SELECT ID FROM $wpdb->posts WHERE post_type = %s AND (post_status = %s or post_status = %s)";
        $completeQuery = $wpdb->prepare($query, $post_type, 'publish', 'draft');
        $events = $wpdb->get_results($completeQuery);

        if (count($events) == 0) {
            return;
        }

        $db_table = $wpdb->prefix."integrate_occasions";
        $query = "SELECT ID, event_id FROM $db_table WHERE event_id = %s";
        // Loop through events and check if occasions exist
        foreach ($events as $e) {
            $completeQuery = $wpdb->prepare($query, $e->ID);
            $results = $wpdb->get_results($completeQuery);
            // Delete event if occasions is empty
            if (count($results) == 0) {
                wp_delete_post($e->ID, true);
            }
        }

        return;
    }

Remove expired events from databse
@return void


public function filterTaxonomies($taxonomies, $type)
    {
        $passes = true;
        $tax_array = ($type == 0) ? get_field('event_filter_cat', 'options') : get_field('event_filter_tag', 'options');

        if (!empty($tax_array)) {
            $filters = array_map('trim', explode(',', $tax_array));
            $taxLower = array_map('strtolower', $taxonomies);
            $passes = false;

            foreach ($filters as $filter) {
                if (in_array(strtolower($filter), $taxLower)) {
                    $passes = true;
                }
            }
        }

        return $passes;
    }

public function filterTaxonomies ( $ taxonomies , $ type ) { $ passes = true ; $ tax_array = ( $ type == 0 ) ? get_field ( 'event_filter_cat' , 'options' ) : get_field ( 'event_filter_tag' , 'options' ) ; if ( ! empty ( $ tax_array ) ) { $ filters = array_map ( 'trim' , explode ( ',' , $ tax_array ) ) ; $ taxLower = array_map ( 'strtolower' , $ taxonomies ) ; $ passes = false ; foreach ( $ filters as $ filter ) { if ( in_array ( strtolower ( $ filter ) , $ taxLower ) ) { $ passes = true ; } } } return $ passes ; }

Filter by taxonomies, if add or not to add
@param  array $taxonomies All taxonomies
@param  int   $type       Type of taxonomy, 0 = category, 1 = tag
@return bool

Filter by taxonomies if add or not to add


public function deleteEmptyTaxonomies()
    {
        if (!empty(get_object_taxonomies('event'))) {
            foreach (get_object_taxonomies('event') as $taxonomy) {
                // Skip Event Groups and categories
                if ($taxonomy == 'event_groups' || $taxonomy == 'event_categories') {
                    continue;
                }

                $terms = get_terms(
                    array(
                        'taxonomy' => $taxonomy,
                        'hide_empty' => false,
                        'childless' => true,
                    )
                );

                foreach ($terms as $term) {
                    if ($term->count == 0) {
                        wp_delete_term($term->term_id, $taxonomy);
                    }
                }
            }
        }
    }

public
function
deleteEmptyTaxonomies
(
)
{
if
(
!
empty
(
get_object_taxonomies
(
'event'
)
)
)
{
foreach
(
get_object_taxonomies
(
'event'
)
as
$
taxonomy
)
{
// Skip Event Groups and categories
if
(
$
taxonomy
==
'event_groups'
||
$
taxonomy
==
'event_categories'
)
{
continue
;
}
$
terms
=
get_terms
(
array
(
'taxonomy'
=>
$
taxonomy
,
'hide_empty'
=>
false
,
'childless'
=>
true
,
)
)
;
foreach
(
$
terms
as
$
term
)
{
if
(
$
term
->
count
==
0
)
{
wp_delete_term
(
$
term
->
term_id
,
$
taxonomy
)
;
}
}
}
}
}

Delete empty event taxonomies
@return void


public function renderLocationList($post)
    {
        $api_url = get_field('event_api_url', 'option');
        $location_endpoint = rtrim($api_url, '/') . '/location/complete';
        @$json = file_get_contents($location_endpoint);

        if ($json == false) {
            $markup = '' . __('Something went wrong, pleae check your API url.', 'event-integration') . '';
        } else {
            $locations = json_decode($json);
            $location_data = get_field('mod_location_data', $post->ID);
            $current = ($location_data) ? $location_data->id : false;

            if (!empty($locations)) {
                $markup = '<select name="mod_location">';
                foreach ($locations as $location) {
                    $selected = ($current == $location->id) ? 'selected' : '';
                    $markup .= '<option value="' . $location->id . '" ' . $selected . '>' . $location->title . '</option>';
                }
                $markup .= '</select>';
            } else {
                $markup = '' . __('No locations found', 'event-integration') . '';
            }
        }

        echo $markup;
    }

Display a list with location from API
@param  Obj $post Current post object
@return string Markup


public function saveLocation($post_id, $post, $update)
    {
        $api_url = get_field('event_api_url', 'option');
        $location_endpoint = rtrim($api_url, '/') . '/location/';

        if (isset($_POST['mod_location'])) {
            $location_endpoint = rtrim($api_url, '/') . '/location/' . $_POST['mod_location'] . '?_embed';
            @$json = file_get_contents($location_endpoint);
            if ($json != false) {
                $location = json_decode($json);
                update_post_meta($post_id, 'mod_location_data', $location);
            }
        }

        return;
    }

public function saveLocation ( $ post_id , $ post , $ update ) { $ api_url = get_field ( 'event_api_url' , 'option' ) ; $ location_endpoint = rtrim ( $ api_url , '/' ) . '/location/' ; if ( isset ( $ _POST [ 'mod_location' ] ) ) { $ location_endpoint = rtrim ( $ api_url , '/' ) . '/location/' . $ _POST [ 'mod_location' ] . '?_embed' ; @ $ json = file_get_contents ( $ location_endpoint ) ; if ( $ json != false ) { $ location = json_decode ( $ json ) ; update_post_meta ( $ post_id , 'mod_location_data' , $ location ) ; } } return ; }

Save location module metadata on save
@param int   $post_id    The post ID
@param post  $post       The post object
@param bool  $update     Whether this is an existing post being updated or not


public static function getRevManifest()
    {
        $jsonPath = EVENTMANAGERINTEGRATION_PATH . apply_filters('EventManagerIntegration/Helper/CacheBust/RevManifestPath', 'dist/rev-manifest.json');

        if (file_exists($jsonPath)) {
            return json_decode(file_get_contents($jsonPath), true);
        } elseif (WP_DEBUG) {
            echo '
Error: Assets not built. Go to ' . EVENTMANAGERINTEGRATION_PATH . ' and run gulp. See '. EVENTMANAGERINTEGRATION_PATH . 'README.md for more info.
';
        }
    }

'<div style="color:red">Error: Assets not built. Go to '

Decode assets json to array
@return array containg assets filenames


public function removeMetaBoxes()
    {
        if (function_exists('get_field')) {
            if (get_field('event_update_button', 'option') == false) {
                remove_meta_box('submitdiv', $this->post_type, 'side');
            }
        }
        remove_meta_box('acf-group_56c33cf1470dc', $this->post_type, 'side');
        remove_meta_box('pageparentdiv', $this->post_type, 'side');
    }

public function removeMetaBoxes ( ) { if ( function_exists ( 'get_field' ) ) { if ( get_field ( 'event_update_button' , 'option' ) == false ) { remove_meta_box ( 'submitdiv' , $ this -> post_type , 'side' ) ; } } remove_meta_box ( 'acf-group_56c33cf1470dc' , $ this -> post_type , 'side' ) ; remove_meta_box ( 'pageparentdiv' , $ this -> post_type , 'side' ) ; }