OOPI is a WordPress plugin providing a developer friendly library for importing data into WordPress from external sources.
Open Issues: 1
- php: >=7.4 || ^8.0 || ^8.1
- composer/installers: ^1.0.12 || ^2
- 10up/wp_mock: ^0.4.2
- phpunit/phpunit: ^9
- roave/security-advisories: dev-latest
This package is not auto-updated.
Last update: 2023-03-25 18:56:21 UTC
OOPI (an acronym from "object-oriented, programming and importer) is a WordPress plugin providing an object-oriented library to ease and give structure for importing data into WordPress from external sources.
Install the plugin with Composer:
composer require devgeniem/wp-oopi
Then activate the plugin from the WordPress dashboard or with the WP-CLI.
wp plugin activate wp-oopi
How does it work?
The plugin provides functionalities for importing various data types. You can think of the importer as an integration layer between your custom data source and the WordPress database. Your job is to format the data into OOPI objects by manually using class constructors or the provided helper factories. If your external data source can provide the data in the OOPI data format, your job is as simple as decoding the data into a PHP object and then passing it for a
create method in a importable factory.
OOPI provides the saving process for your data by using WordPress functions to interact with the database. With OOPI you get a standardized way of building developer friendly importers and it helps you write better code by providing important features such as error handling and logging.
An import is a two step process. First step is to create an importable object. If it is a post you are importing, then you create a
\Geniem\Oopi\Importable\PostImportable object. You can use the class constructor directly or use the easy way and use a provided factory method. The
PostFactory::create method takes a unique OOPI id and a full importer object as a parameter, validates all fields and converts the data into strictly typed objects. During the import process, the OOPI id is stored in (post) meta and it is used to identify your imported object after it is initially created. Subsequent imports with the same OOPI id will update the matching post.
After your data is set, the actual importing is done by calling the importable's
import() method. This method uses composition to call the actual import method of an importer. All importers implement the
\Geniem\Oopi\Intefaces\Importer inteface and all importables should contain an importer. The
import method will handle saving all the data attached to the importable object into WordPress database.
Importables allow changing the import process by passing an importer object for the class constructor. If none is set, all importables get a default importer provided by OOPI during the instantiation.
See the post example.
You can import terms along your posts. But if you require more control over your term importing, for example to prevent importing posts after erroneous term imports, you can use the OOPI importing process for terms.
To get started, create an importable by instantiating a
\Geniem\Oopi\Importable\TermImportable directly and use setters to set your data or use the
\Geniem\Oopi\Factory\Importable\TermFactory::create method. After your data is set, import the term object by calling its
import method. Just like with a post imortable, this will call the
import method of the attached term importer.
See the term example.
Attachments can be imported along post importables, but if required, you can import attachments in a dedicated process. Importing attachments follows the same process as posts and terms. Create an attachment importable by instantiating the
\Geniem\Oopi\Importable\AttachmentImportable class or by calling the
\Geniem\Oopi\Factory\Importable\AttachmentFactory::create method. After setting all the data, call the
import method of the importable. This will trigger the import process by calling the
import method in the attached importer.
Attachments are problematic when importing data into WordPress. OOPI attempts to make it as simple as possible by handling the file transfering from the provided source (
src attribute), but bear in mind, downloading and uploading files from external sources and into WordPress will take time. With OOPI, you are fully in control of your importing process and you might run into timeouts if your server configurations are not properly set to handle your workloads.
Note! OOPI supports only image MIME types currently.
Customizing the import process
To customize the term importing process, create your own importable class extending the corresponding importer provided by OOPI or by directly implementing the
\Geniem\Oopi\Interfaces\Importable interface. For example, to customize the attachment import process, extend the
\Geniem\Oopi\Importer\AttachmentImporter and override its methods as needed. To override the default importer instance in an importable, instantiate your custom importer and pass it for your importable constructor or factory.
Importables have attributes that are saved during the import process. Each attribute class should have a corresponding saver for handling the database interactions. For example, post meta is an attribute you can attach to post importables. When the post is imported, the post meta attribute is saved with the post meta saver using the WordPress post meta functions.
See the list of all available attributes here.
OOPI supports localization with the
\Geniem\Oopi\Attribute\Language attribute. Currently, OOPI provides a language saver for Polylang and is able to localize posts, terms and attachments.
The properties for a language attribute are:
(Required)- The related importable object.
(Required)- The locale string (e.q. 'en').
(Optional)- The OOPI id of importable in the main language. It is used to map translations.
(Optional)- The language saver.
To automatically map your importables as translations of one another, set the
main_oopi_id for importables in other than the main language. For example, if your WordPress site's main language is English, set the OOPI id of the English importable as the main OOPI id for its translations. Import the main language always first for OOPI to be able to map the main object for other languages.
OOPI supports importing Advanced Custom Fields field data with the
\Geniem\Oopi\Attribute\AcfField attribute. The
\Geniem\Oopi\Attribute\Saver\AcfFieldSaver controls the saving process and can handle post and term fields. Note that the field saving is limited by the functionalities of the ACF's
::create( $oopi_id, $data )
(string) (Required)The unique external identifier for your importable.
(array|object) (Required)An array/object containing the following keys:
WP_Postinstance or an array/object containing the keys and values for
(array) (Optional)An array of attachment objects containing:
(string) (Required)An unique id identifying the object in the external data source.
(string) (Required)The source from which to upload the image into WordPress.
(string) (Optional)The alt text for the image. This is saved into postmeta.
(string) (Optional)The file caption text.
(string) (Optional)The file description text.
(bool) (Optional)Defines if the attachment should set as the post thumbnail.
(array) (Optional)An array of arrays or objects containing:
(string) (Required)The meta key.
(mixed) (Required)The meta value.
(array) (Optional)An array containing either-or:
(Geniem\Oopi\Importable\TermImportable)OOPI Term importable.
- If the OOPI term importable holds a WP_Term object, importing will override existing term data.
(string) (Required)All terms must contain an id.
WP_Term|object|array (Optional)An object/array containing properties of a WP_Term object or a
WP_Termobject. If set, data for the Term importable will be mapped from the object.
(string) (Required)The taxonomy term slug. The term slugs must be unique, ie. they can not collide between different language versions.
(string) (Required)The taxonomy term display name.
(string) (Required)The taxonomy name, for example
(array) (Optional)An array of Advanced Custom Fields data objects containing:
(string) (Required)The ACF field type (types).
(string) (Required)The ACF field key. This must be the unique key defined for the field.
(mixed) (Required)The data value matching the field type specifications.
(Geniem\Oopi\Attribute\Language|object|array) (Optional)Localization information in an OOPI Language object or raw data. Raw data will be converted into a Language instance.
\Geniem\Oopi\Settings\ class is used to set and load all plugin settings. It uses the following settings that are overridable with constants.
- Setting key
OOPI_ID_PREFIX, default value
- Setting key
OOPI_ATTACHMENT_PREFIX, default value
- Setting key
OOPI_LOG_ERRORS, default value
- Setting key
OOPI_TRANSIENT_KEY, default value
- Setting key
OOPI_TRANSIENT_EXPIRATION, default value
- Setting key
OOPI_TMP_FOLDER, default value
'/tmp/'. Used for handling attachments.
- Setting key
OOPI_TABLE_NAME, default value
- Setting key
OOPI_LOG_STATUS_OK, default value
- Setting key
OOPI_LOG_STATUS_FAIL, default value
- Setting key
$oopi_id_prefix = \Geniem\Oopi\Settings::get( 'id_prefix' );
To override the transient expiration time set the following constant before the setting is used the first time.
define( 'OOPI_TRANSIENT_EXPIRATION', MONTH_IN_SECONDS );
To ignore SSL Certificate verification errors in your importer, you can define
OOPI_IGNORE_SSL as true.
define( 'OOPI_IGNORE_SSL', true );
OOPI uses a generalized error handling. An instance of the error handler is passed as a dependecy to all instances attached to an importable. If an error occurs, the error handler logs (by default logging is enabled) and stores the error in the handler instance. If there where errors during the import process, an exception is thrown for you to catch.
You can customize the error handling process by overriding the default error handler. To do so, create a class implementing the
Geniem\Oopi\Interfaces\ErrorHandler interface and override the default handler instance with your instance by passing it for factories or class constructors.
The plugin creates a custom table into the WordPress database called
oopi_log. This table holds log entries of imports (currently only for posts) and contains the following columns:
idLog entry id.
oopi_idThe importer object id.
wp_idThe WordPress post id of the importer object. Stored only if the
save()is run successfully.
import_date_gmtA GMT timestamp of the import date in MySQL datetime format.
dataThe importer object data containing all properties including errors.
statusThe import status:
The log provides a rollback feature. If an import fails the importer tries to roll back the previous successful import. If no previous imports with the
OK status are found, the imported object is set into
draft state to prevent front-end users from accessing posts with malformed data.
To disable the rollback feature set the
OOPI_ROLLBACK_DISABLE constant with a value of
The plugin registers a log cleaner cronjob on plugin activation. The cronjob deletes all rows from the log table by status and import date threshold. Both the statuses and the threshold can be modified with filters
The cronjob is run with
'daily' interval by default, it can be changed with
OOPI_CRON_INTERVAL_CLEAN_LOG constant. Cronjob scheduling can be disabled by defining the constant as
The plugin code is tested using PHPUnit. Local test can be run using the provided Docker container with Docker Compose. The following command will build the container and start it. The container's CMD script will run PHPUnit once and then set up pywathc to watch changes in the
./tests directory. If changes are made, test are rerun.
$ docker compose up
If you need to debug the tests, the container comes with Xdebug 3 for step debugging. You need to set up PHPUnit using the provided docker container as a remote interpreter. For this, use the
php service in the Docker Compose file and the PHPUnit executable
vendor/bin/phpunit. The full path to the executable inside the container is
This repository also contains a GitHub integration for Travic CI. All commits to the
master branch will be automatically tested with Travis.