With this library you can easy query your data using an On Page ® API token.
To install this library in your existing composer project, or update to the latest version, you can launch:
composer require onpage-dev/onpage-php:^v1.2
Of course, remember to include the composer autoload:
<?php
require 'vendor/autoload.php';
To start, you need to connect to an On Page Schema (project) using the following function:
$schema = \OnPage\Schema::fromToken('MY-API-TOKEN');
// Retrieve all records of a resource (returns a laravel collection of \OnPage\Thing)
$products = $schema->query('products')->all();
foreach ($products as $prod) {
// ...
}
// Get only the first item
$prod = $api->query('products')->first();
// Retrieve all records of a resource (returns a laravel collection of \OnPage\Thing)
// NOTE: system fields must be prefixed with the _ symbol
$api->query('products')
->where('_id', 42) // = is the default operator
->where('_created_at', '<', '2024-01-01 00:00:00')
->where('_updated_at', '>=', '2024-01-01 00:00:00')
->first();
// Other filters
$api->query('products')
->where('name', 'like', 'shoes') // you can specify a different operator
->where('category.name', 'Nike') // you can query relations
->where('dimension', '>', 10) // you get it
->whereIn('size', [42, 43, 44])
->all(); // returns a collection with all your records
// Join filters with the OR clause: get all products for the adidas or nike brands
$api->query('products')
->whereOneOf(function(\OnPage\QueryBuilder $q) {
->where('price', 'Nike')
->where('brand', 'Adidas')
})
->all();
// Advanced filtering by relation
$api->query('products')
// only retrieve products that have at least one associated category
->whereHas('category')
// only retrieve products that have zero associated categories
->whereHas('category', null, '=', 0)
// only retrieve products that have at least one variant with at least one color
->whereHas('variant.color')
// Only get products that have at least one category that satisfies these 2 conditions:
->whereHas('category', function(\OnPage\QueryBuilder $q) {
$q->where('is_online', true);
$q->where('name', 'like', 'shoes');
})
->all();
// You can just simply move data to trash the same way:
$api->query('products')
->where(...)
->delete();
// Or delete elements bypassing the trash:
$api->query('products')
->where(...)
->delete(forever: true);
// Filter by element status trash, any
$api->query('products')
->where(...)
->delete(forever: true);
Use the val() function to get the first value in a field. Use the values() function to get all values in a field as a collection.
$cat = $api->query('categories')->first();
echo $cat->id; // item ID
echo $cat->created_at; // creation date e.g. 2022-01-01 23:33:00
echo $cat->updated_at; // date of last update to any of the fields e.g. 2022-01-01 23:33:00
echo $cat->order; // global order number (float)
echo $cat->val('name');
echo $cat->val('dimension');
echo $cat->val('description', 'zh'); // you can specify a language
// Or set the default language
$schema->lang = 'zh';
echo $cat->val('name'); // 再见
// You can also set a fallback language
$schema->lang = 'zh';
$schema->fallback_lang = 'en';
echo $cat->val('description'); // English description if chinese description is missing
// The values function is useful for multivalue fields, it will return a laravel collection of values.
echo $cat->values('bullet_points')->implode('; ');
For image
and file
fields, the returned value will be an instance of \OnPage\File::class
.
To get a file or image url use the ->link()
function. The link will point to the original file.
# original size
$product->file('specsheet')->name // icecream-spec.pdf
$product->file('specsheet')->token // R417C0YAM90RF
$product->file('specsheet')->link() // https://acme-inc.onpage.it/api/storage/R417C0YAM90RF?name=icecream-spec.pdf
// Force download (by default the browser will try to preview the file, e.g. pdf/images)
$product->file('specsheet')->link([ 'download' => true ])
// Customize file name
$product->file('specsheet')->link([ 'name' => 'my custom name.pdf' ])
To turn images into a thumbnail add an array of options as shown below:
# maintain proportions width 200px
$product->file('cover_image')->link(['x' => 200])
# maintain proportions height 100px
$product->file('cover_image')->link(['y' => 100])
# crop image to width 200px and height 100px
$product->file('cover_image')->link(['x' => 200, 'y' => 100])
# maintain proportions and contain in a rectangle of width 200px and height 100px
$product->file('cover_image')->link(['x' => 200, 'y' => 100, 'contain' => true])
# convert the image to png (default thumbnail extension is png)
$product->file('cover_image')->link(['x' => 200, 'ext' => 'png'])
// Speed things up by only loading some fields
$api->query('products')->loadFields(['title'])->all();
// You can also limit the fields on a related item
$api->query('products')
->with([ 'colors' ])
->loadRelationFields('colors', ['name', 'image']) // only load 2 fields for the "color" relation
->all();
// Get a mapping between two fields or a field and the thing ID
$api->query('products')->map('code');
// [ 'MYSKU100' => 1827, 'MYSKU101' => 1828, ... ]
$api->query('products')->map('code', 'title');
// [ 'MYSKU100' => 'Apples', 'MYSKU101' => 'Bananas', ... ]
// You need to specify the relations using the "with" method
$cat = $api->query('categories')
->with('subcategories')
->first();
$subcategories = $cat->rel('subcategories');
foreach ($subcategories as $subcategory) {
echo $subcategory->val('name');
}
// You can also preload nested subcategories
$cat = $api->query('categories')
->with('subcategories.articles.colors')
->first();
// Or you can pass the relations as an array
$products_with_colors = $api->query('products')
->with([ 'colors', 'categories' ])
->all();
foreach ($products_with_colors as $prod) {
echo $prod->val('name');
foreach ($prod->colors as $color) {
echo $color->val('name');
}
}
// If you need to filter the related items you want to download, you can do this:
$cat = $api->query('categories')
->with('subcategories.articles.colors')
->filterRelation('subcategories.articles', function(\OnPage\QueryBuilder $q) {
$q->where('is_online', true);
})
->first();
To create or update a record, you need to create a Thing Editor. There are two ways to get a Thing Editor:
- Using the Resource Writer
- Calling
->editor()
on aOp\Thing
This class allows you to edit many records at once. You can easily obtain the editor calling:
$writer = $api->resource('categories')->writer();
Now that you have a Resource Writer, you can use it to create things:
$editor = $writer->createThing();
$editor->set('name', 'Element 1');
$editor->setRel('category', [ 12345 ]); // array with category IDs
...and to update existing things:
$editor = $writer->updateThing(736251); // The id of the element you want to update
$editor->set('description', 'Element 1 description');
Finally, you need to send the request to the On Page server:
// this will create and update all the things as requested above
$writer->save();
$product = $api->query('products')->where('name', 'Plastic Duck')->first();
$editor = $product->editor();
$editor->set('description', 'This yellow plastic duck will be your best friend');
$editor->set('description', '这只黄色塑料鸭将是你最好的朋友', 'zh'); // you can specify language
// Save all the edits at once using the save method
$editor->save();
By default, even if you update a single language, the writer will delete the data on other languages. If you only need to edit certain languages and maintain the current values for the others, you can specify which languages you are working on as follows:
// Update the chinese description without deleting the english description:
$editor = $product->editor();
$editor->setLangs([ 'zh' ]);
$editor->set('description', '这只');
$editor->save();
Just add the language code as the third argument to the set
function:
// Update the value in the default language
$editor->set('description', 'This yellow plastic duck will be your best friend');
// Specify another the language
$editor->set('description', '这只黄色塑料鸭将是你最好的朋友', 'zh');
You can upload files to On Page using the FileUpload class:
$editor->set('image', new \OnPage\FileUpload('/path/to/bird.jpg')); // upload file
Or you can also upload a file using a public URL:
$editor->set('image', 'https://mysite.com/bird_cover.jpg'); // specify file by url
For multivalue fields you only need to replace ->set
with ->setValues
and pass an array of values as the second argument:
$editor->setValues('bullet_points', [
'Durable plastic',
'Bright yellow color',
'Compostable'
]);
To update relations, you can use the ->setRel(relation_name, related_ids)
:
$editor->setRel('features', [
425790,
547023,
240289,
]);
// Retrieve info about the schema:
echo $schema->label;
// Retrieve a resource given its name or ID
$res = $schema->resource('products');
foreach ($res->fields() as $field) {
echo "$field->getLabel()\n"; // Main image
echo "$field->getLabel('zh')\n"; // "Main Image" but in Chinese
echo "$field->name\n"; // "main_image"
echo "$field->type\n"; // string|file|image|real|int|text|...
echo "$field->unit\n"; // null|kg|...
echo "$field->is_multiple\n"; // true|false
echo "$field->is_translatable\n"; // true|false
}