Skip to content

Instantly share code, notes, and snippets.

@schwarzdesign schwarzdesign/functions.php Secret
Created Jun 4, 2019

Embed
What would you like to do?
Extract ProcessWire Page fields
/**
* Extract the specified fields from the passed page and returns it as a stdClass
* object with properties based on the field names.
*
* @var Page $page The page to extract fields from.
* @var array $fields An array of field names to extract.
* @var array $internal_fields Additional internal fields to extract.
*/
function extractPageFields(
Page $page,
array $fields,
array $internal_fields = ['name', 'modified', 'id'],
array $image_sizes = [360, 576, 768, 1200, 1536]
): object {
$data = new class{};
foreach ($internal_fields as $field) {
$data->{$field} = $page->{$field};
}
foreach ($fields as $field) {
$type = $page->fields->{$field}->getFieldType();
if ($type instanceof FieldtypeImage) {
if ($page->{$field} instanceof Pageimage) {
// extract single images as one item
$data->{$field} = new class {};
$data->{$field}->description = $page->{$field}->description();
$data->{$field}->path = dirname($page->{$field}->url()) . '/';
if (!empty($image_sizes)) {
$data->{$field}->sizes = generateSizes($page->{$field}, $image_sizes);
}
} elseif ($page->{$field} instanceof Pageimages) {
// extract multiple images as an array
$data->{$field} = [];
foreach ($page->{$field} as $image) {
$current = new class {};
$current->description = $image->description();
$current->path = dirname($image->url()) . '/';
if (!empty($image_sizes)) {
$current->sizes = generateSizes($image, $image_sizes);
}
$data->{$field}[] = $current;
}
} elseif ($page->{$field} === NULL) {
// do nothing if the field is empty
} else {
throw new \Exception('Unknown field type.');
}
} elseif ($type instanceof FieldtypePage) {
$data->{$field} = [];
foreach ($page->{$field} as $item) {
$data->{$field}[] = $item->id;
}
} elseif ($type instanceof FieldtypeTextareas) {
foreach ($page->{$field} as $name => $item) {
$data->{$name} = $item;
}
} elseif ($type instanceof FieldtypeRepeater) {
$data->{$field} = [];
foreach ($page->{$field} as $item) {
$data->{$field}[] = extractAllPageFields($item, []);
}
} else {
$data->{$field} = $page->get($field);
}
}
return $data;
}
/**
* Generate alternate image sizes for the given image. Returns an array containing
* objects for all created sizes, with "w" as the width and "file" as the basename
* of the file (no need to include the full path each time). Doesn't create variants
* larger than the original image.
*
* @param Pageimage $image The image to create variants of.
* @param array $sizes An array of integers (the sizes you want).
* @return void
*/
function generateSizes(Pageimage $image, array $sizes): array {
sort($sizes);
$generated = [];
foreach ($sizes as $size) {
$current = new class {};
if ($image->width() >= $size) {
$current->w = $size;
$current->file = basename($image->width($size)->url());
$generated[] = $current;
} else {
// if the requested size is higher than the size of the original,
// include the original as is and stop the loop
$current->w = $image->width();
$current->file = basename($image->url());
$generated[] = $current;
break;
}
}
return $generated;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.