openlayers-8.x-4.x-dev/src/Openlayers.php
src/Openlayers.php
<?php
namespace Drupal\openlayers;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\Html;
use Drupal\openlayers\Types\ObjectInterface;
use Drupal\Core\Messenger\MessengerTrait;
/**
* FIX - Insert short comment here.
*/
class Openlayers {
use MessengerTrait;
/**
* Gets a list of available plugin types.
*
* @param string $object_type
* The plugin type.
*
* @return array
* Openlayers objects types options.
*/
public static function getOlObjectsOptions($object_type) {
$options = array();
$service_basename = 'openlayers.' . $object_type;
foreach (\OpenlayersDrupal::service($service_basename)->getDefinitions() as $data) {
$name = isset($data['label']) ? $data['label'] : $data['id'];
$options[$service_basename . ':' . $data['id']] = $name;
}
asort($options);
return $options;
}
/**
* Gets a list of Openlayers exportable.
*
* @param string $type
* The plugin .
*
* @return array
* Openlayers object instance.
*/
public static function loadAllAsOptions($type = NULL) {
$options = array();
$type = Unicode::ucfirst(mb_strtolower($type));
$nids = \Drupal::entityQuery('openlayers_' . mb_strtolower($type))
->accessCheck(FALSE)
->execute();
// TODO - there has to be a better way than this
if ($type == 'Component') {
$objects = \Drupal\openlayers\Entity\OpenlayersComponent::loadMultiple($nids);
}
if ($type == 'Control') {
$objects = \Drupal\openlayers\Entity\OpenlayersControl::loadMultiple($nids);
}
if ($type == 'Layer') {
$objects = \Drupal\openlayers\Entity\OpenlayersLayer::loadMultiple($nids);
}
if ($type == 'Style') {
$objects = \Drupal\openlayers\Entity\OpenlayersStyle::loadMultiple($nids);
}
if (!$objects) {
$objects = [];
}
foreach ($objects as $machine_name => $data) {
if (is_object($data)) {
$options[$machine_name] = $data->label;
}
}
return $options;
}
/**
* Gets all available OL objects.
*
* @param string $type
* The plugin type.
*
* @return array
* Array of Openlayers CTools object instances. (stdClass)
*/
public static function loadAllExportable($type = NULL) {
ctools_include('export');
$exports = ctools_export_crud_load_all('openlayers_' . mb_strtolower(check_plain($type)) . 's');
uasort($exports, function ($a, $b) {
return strcasecmp($a->name, $b->name);
});
return $exports;
}
/**
* Load all objects.
*
* @param string $object_type
* Type of object to load:
* map|layer|source|control|interaction|style|component.
*
* @return \Drupal\openlayers\Types\ObjectInterface[]
* The array of objects.
*/
public static function loadAll($object_type = NULL) {
$objects = array();
foreach (Openlayers::loadAllExportable($object_type) as $exportable) {
if (is_object($exportable)) {
$objects[$exportable->machine_name] = Openlayers::load($object_type, $exportable);
}
}
return $objects;
}
/**
* Create an object instance for an export.
*
* @param string $object_type
* The object type to look up. See openlayers_object_types() for a list of
* available object types.
* @param array|string|object $export
* The exported object.
*
* @return \Drupal\openlayers\Types\ObjectInterface|Error
* Returns the instance of the requested object or an instance of
* Error on error.
*/
public static function load($object_type, $export, $options = []) {
/** @var \Drupal\openlayers\Types\ObjectInterface $object */
$object = NULL;
$configuration = array();
$object_type = Unicode::ucfirst(mb_strtolower(Html::escape($object_type)));
if (is_array($export)) {
$configuration = $export;
}
if (is_object($export) && ($export instanceof \StdClass)) {
$array_object = new \ArrayObject($export);
$configuration = $array_object->getArrayCopy();
}
if (is_object($export) && ($export instanceof ObjectInterface)) {
return $export;
}
if (!is_string($export)) {
return NULL;
}
$configuration = [];
$configEntity = \Drupal::config('openlayers.' . strtolower($object_type) . '.' . $export)->get();
if (!isset($configEntity['pluginId'])) {
\Drupal::messenger()->addError('"' . $export . '" does not have a defined Plugin ID.');
return NULL;
}
if (!isset($configEntity['service'])) {
\Drupal::messenger()->addError('"' . $export . '" does not have a defined Service.');
return NULL;
}
// TODO - new idea to get options from config entity into the Openlayers obejct load / collection
if (!isset($configEntity['options'])) {
$configEntity['options'] = [];
}
$configEntity['options'] = array_merge($configEntity['options'], $options);
// TODO - this is a clumsy way of create options array from config entity !! (WIP)
// TODO - separate options from config entity fields (WIP)
$configuration = [];
foreach ($configEntity as $key => $item) {
if (in_array($key, ['pluginId', 'service'])) {
$configuration[$key] = $item;
} else {
$configuration['options'][$key] = $item;
}
}
// TODO - there has to be a better way than this ?
$configuration['machine_name'] = $configuration['options']['id'];
// Invoke the plugin class
$plugin_type = \Drupal::service('plugin.manager.openlayers');
// Get a list of available plugins
$plugin_definitions = $plugin_type->getDefinitions(strtolower($object_type));
if (in_array($configEntity['pluginId'], array_keys($plugin_definitions))) {
try {
// Create a preconfigured instance of a plugin
$object = $plugin_type->createInstance($configEntity['pluginId'], $configuration);
}
//catch exception
catch(PluginNotFoundException $e) {
\Drupal::messenger()->addError($e->getMessage() . '.');
return NULL;
}
//catch exception
catch(PluginException $e) {
\Drupal::messenger()->addError($e->getMessage());
return NULL;
}
} else {
\Drupal::messenger()->addError('Plugin "' . $export . '" not found.');
return NULL;
}
return $object->init();
}
/**
* Save an object in the database.
*
* @param \Drupal\openlayers\Types\ObjectInterface $object
* The object to save.
*/
public static function XXsave(ObjectInterface $object) {
ctools_include('export');
$configuration = $object->getConfiguration();
$export = $object->getExport();
ctools_export_crud_save($configuration['table'], $export);
}
/**
* Return the list of Openlayers plugins type this module provides.
*
* @param array $filter
* The values to filter out of the result array.
*
* @return string[]
* Return an array of strings. Those strings are the plugin type name
* in lowercase.
*/
public static function getPluginTypes(array $filter = array()) {
$plugins = [
'component' => 'component',
'control' => 'control',
'interaction' => 'interaction',
'layer' => 'layer',
'map' => 'map',
'source' => 'source',
'style' => 'style'
];
asort($plugins);
return array_udiff(array_values($plugins), $filter, 'strcasecmp');
}
/**
* Return information about the Openlayers 3 if installed.
*
* @return array|false
* Return an array from hook_libraries_info() if the library is found,
* otherwise return False.
*/
public static function getLibrary() {
return libraries_detect('openlayers3');
}
/**
* Return the version of the Openlayers library in use.
*
* @return string
* Return the version of the Openlayers library set in the configuration.
*/
public static function getLibraryVersion() {
$version = Config::get('openlayers.variant');
if (strpos($version, 'cdn-') !== FALSE) {
return $version;
}
if (strpos($version, 'local-') !== FALSE) {
return $version;
}
if(!is_dir(libraries_get_path('openlayers3') . '/versions')) {
return FALSE;
}
$version = array_diff(scandir(libraries_get_path('openlayers3') . '/versions'), ['.', '..']);
rsort($version);
$version = current($version);
return str_replace('v', 'local-', $version);
}
/**
* Apply a function recursively to all the value of an array.
*
* @param callable $func
* Function to call.
* @param array $arr
* The array to process.
*
* @return array
* The processed array
*/
public static function arrayMapRecursive(callable $func, array $arr) {
/*
// This is the PHP Version >= 5.5
// $func must be a callable.
array_walk_recursive($arr, function(&$v) use ($func) {
$v = $func($v);
});
return $arr;
*/
foreach ($arr as $key => $value) {
if (is_array($arr[$key])) {
$arr[$key] = self::arrayMapRecursive($func, $arr[$key]);
}
else {
$arr[$key] = call_user_func($func, $arr[$key]);
}
}
return $arr;
}
/**
* Ensures a value is of type float or integer if it is a numeric value.
*
* @param mixed $var
* The value to type cast if possible.
*
* @return float|mixed
* The variable - casted to type float if possible.
*/
public static function floatvalIfNumeric($var) {
if (is_numeric($var)) {
return is_float($var + 0) ? floatval($var) : intval($var);
}
return $var;
}
/**
* Recursively removes empty values from an array.
*
* Empty means empty($value) AND not 0.
*
* @param array $array
* The array to clean.
*
* @return array
* The cleaned array.
*/
public static function removeEmptyElements(array $array) {
foreach ($array as $key => $value) {
if ($value === '' && $value !== 0) {
unset($array[$key]);
}
elseif (is_array($value)) {
$array[$key] = self::removeEmptyElements($value);
}
}
return $array;
}
/**
* Returns an array with positioning options.
*
* @return string[]
* Array with positioning options.
*/
public static function positioningOptions() {
return array(
'bottom-left' => t('bottom-left'),
'bottom-center' => t('bottom-center'),
'bottom-right' => t('bottom-right'),
'center-left' => t('center-left'),
'center-center' => t('center-center'),
'center-right' => t('center-right'),
'top-left' => t('top-left'),
'top-center' => t('top-center'),
'top-right' => t('top-right'),
);
}
/**
* The list of geometries available.
*
* @return string[]
* The list of geometries.
*/
public static function getGeometryTypes() {
return array(
'Point' => t('Point'),
'MultiPoint' => t('MultiPoint'),
'LineString' => t('LineString'),
'LinearRing' => t('LinearRing'),
'MultiLineString' => t('MultiLineString'),
'Polygon' => t('Polygon'),
'MultiPolygon' => t('MultiPolygon'),
'GeometryCollection' => t('GeometryCollection'),
'Circle' => t('Circle'),
);
}
/**
* Returns the list of attached libraries or js/css files.
*
* @return array
* Array containing the attachment libraries to load.
*/
public static function getAttached() {
$attached = array();
if (!self::detectLibrary()) {
global $base_url;
$configuration = array(
'errorMessage' => t('Unable to load the Openlayers JS library variant,
please <a href="@openlayers_admin">update your settings</a> and select
a valid variant of the library.',
array('@openlayers_admin' => $base_url . '/admin/structure/openlayers')),
);
\OpenlayersDrupal::service('openlayers.Types')->createInstance('Error', $configuration)->init();
return $attached;
}
$attached['libraries_load'] = array(
'openlayers3' => array(
'openlayers3',
self::getLibraryVersion(),
),
);
if (Config::get('openlayers.debug', FALSE)) {
$attached['libraries_load']['openlayers3_integration'] =
array('openlayers3_integration', 'debug');
};
return $attached;
}
/**
* Check if the Openlayers library and settings are properly found.
*
* @return bool|array
* Return the library array is found, FALSE otherwise.
*/
public static function detectLibrary() {
$library = libraries_detect('openlayers3');
return isset($library['variants'][self::getLibraryVersion()]) ? $library : FALSE;
}
}
