src/Common/Functions/DbFunction.php line 425
<?php
namespace App\Common\Functions;
use App\Common\Functions\Filters\Main;
use App\Functions\Common\Variables;
use App\Functions\PreSave\Main as PreSaveMain;
use Symfony\Component\Mercure\Hub;
use Symfony\Component\Mercure\Jwt\StaticTokenProvider;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
class DbFunction
{
public const HUB_URL = 'https://mer-hub.ukkera.com/.well-known/mercure';
public const TOKEN = 'eyJhbGciOiJIUzI1NiJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdLCJwYXlsb2FkIjp7InVzZXIiOiJodHRwczovL2Npa2kudWtrZXJhLmNvbS8iLCJyZW1vdGVBZGRyIjoiMTI3LjAuMC4xIn19fQ.yb2G4txCdqFgIaoXSg41UDVsEq1TptEMSIBUKlII92E';
public static function FetchExtra($dm, $fetch)
{
$value = [];
foreach ($fetch as $key => $item) {
$value[$key] = self::fetchWithKeys($dm, $item['filters'] ?? [], $item['keys'] ?? ['id'], $item['module'] ?? $key, $item['aggs'] ?? [], $item['props'] ?? ['hydrate' => true]);
}
return $value;
}
public static function buildHub()
{
$hub = new Hub(self::HUB_URL, new StaticTokenProvider(self::TOKEN));
return $hub;
}
public static function AddOrUpdateModel($module, $dm, $serializer, $ev)
{
$model = Helpers::get_module($module);
$repo = $dm->getRepository($model);
$db_val = null;
if ($ev['id'] ?? false) {
$db_val = $repo->findOneBy(['id' => $ev['id']]);
}
return self::AddOrUpdate($model, $dm, $serializer, $ev, $db_val);
}
public static function AddOrUpdate($model, $dm, $serializer, $ev, $db_val = null, $props = [], $params = [])
{
$cs = Helpers::get_model_config($model);
$pre_save = Helpers::getFun($model, 'PreSave');
$hooks = $cs->hooks ?? [];
$validate_fun = Helpers::getFun($model, 'Validations');
$repo = $dm->getRepository($model);
$translations = $ev['translate'] ?? [];
$id = $ev['id'] ?? $ev['pid'] ?? null;
if ($cs->edits ?? false) {
Helpers::mapping_from_account($ev, $cs->edits);
}
if ($cs->inits ?? false) {
Helpers::inits_functions($ev, $cs->inits);
}
if ($id && !$db_val) {
$db_val = $repo->findOneBy(['id' => $id]);
}
if ($id && ($db_val ?? false)) {
$saves = $serializer->deserialize(json_encode($ev), $model, 'json', [...Variables::DESERIALZER_OPTIONS, ObjectNormalizer::DEEP_OBJECT_TO_POPULATE => true, 'object_to_populate' => clone $db_val, 'dm' => $dm, 'serializer' => $serializer, 'creating' => false]);
if ($pre_save) {
$saves->creating = false;
$saves->remove = $ev['remove'] ?? false;
$pre_save->invoke((object) [], $dm, $saves, $serializer, $db_val, $props, $params);
}
if($hooks['pre_save'] ?? false) {
$saves->creating = false;
$saves->remove = $ev['remove'] ?? false;
PreSaveMain::handler($hooks['pre_save'], $dm, $saves, $serializer, $db_val, $props, $params);
}
// dd($saves, $ev, $db_val->app, $saves->app);
$dm->merge($saves);
$dm->flush();
if ($ev['remove'] ?? false) {
// try{
// dd(get_class_methods($db_val));
$can_remove = $db_val->checkRemoval();
if (!$can_remove) {
return ['error' => 'cannot remove this data'];
}
$dm->remove($db_val);
// }catch(\Exception $ex){
// $dm->persist($db_val);
// }
$dm->flush();
return null;
}
self::CreateTranslations($saves, $dm, $translations);
return $id;
}
if ($ev['remove'] ?? false) {
return null;
}
if ($cs->mappings ?? false) {
Helpers::mapping_from_account($ev, $cs->mappings);
}
$value = $serializer->deserialize(json_encode($ev), $model, 'json', [...Variables::DESERIALZER_OPTIONS, 'dm' => $dm, 'serializer' => $serializer, 'creating' => true]);
if ($validate_fun) {
$v_out = $validate_fun->invoke((object) [], $dm, $value, $serializer, (object) [], $props, $params);
if ($v_out) {
return $v_out->getId();
}
}
if ($cs->generate ?? false) {
if (!$id) {
$id = Main::generate_id_from_vals($value, $cs->generate);
}
}
if ($id) {
$value->id = $id;
}
$dm->persist($value);
$dm->flush();
if ($pre_save) {
$value->creating = true;
try {
$pre_save->invoke((object) [], $dm, $value, $serializer, (object) [], $props, $params);
if($hooks['pre_save'] ?? false) {
PreSaveMain::handler($hooks['pre_save'], $dm, $value, $serializer, $db_val, $props, $params);
}
} catch (\Throwable $ex) {
$dm->remove($value);
$dm->flush();
dd($ex);
}
}
$serializer->deserialize(json_encode([...$ev, 'id' => $value->id]), $model, 'json', ['object_to_populate' => clone $value, ObjectNormalizer::DEEP_OBJECT_TO_POPULATE => true, ...Variables::DESERIALZER_OPTIONS, 'dm' => $dm, 'serializer' => $serializer, 'creating' => false]);
$dm->flush();
self::CreateTranslations($value, $dm, $translations);
return $value->id;
}
public static function FindTranslations($mainValue, $dm)
{
$repository = $dm->getRepository('\\Gedmo\\Translatable\\Document\\Translation');
return $repository->findTranslations($mainValue);
}
public static function runModuleValidation($module, $inputs, $dm, $serializer, $props, $params)
{
$model = Helpers::get_module($module);
$error_validation_fun = Helpers::getFun($model, 'ErrorValidations');
if ($error_validation_fun) {
foreach ($inputs as $key => $values) {
foreach ($values as $vs => $value) {
$v_out = $error_validation_fun->invoke((object) [], $dm, (object) $value, $serializer, (object) [], $props, $params);
if ($v_out) {
return $v_out;
}
}
}
}
}
public static function GetByIds($model, $em, $data, $col, $key = 'id')
{
$entity = Helpers::get_module($model)['model'];
$ids = $col ? array_column($data, $col) : $data;
// dd($ids);
$qb = $em->createQueryBuilder();
$qb->select('m');
$qb->from($entity, 'm');
$qb->where($qb->expr()->in("m.$key", '?1'));
return $qb->setParameters(['1' => $ids])->getQuery()->getResult();
}
public static function resetUserPassword($dm, $user, $password)
{
if ($user) {
$user->reset_code = null;
$user->reset_code_date = null;
$user->setPassword($password);
$dm->persist($user);
$dm->flush();
}
}
public static function CreateTranslations($mainValue, $dm, $translations)
{
if (count($translations)) {
$repository = $dm->getRepository('\\Gedmo\\Translatable\\Document\\Translation');
foreach ($translations as $field => $value) {
foreach ($value as $lang => $val) {
$repository->translate($mainValue, $field, $lang, $val);
}
$repository->translate($mainValue, $field, 'en', $mainValue->{$field});
}
$dm->flush();
}
}
public static function FindAndUpdateModel($module, $dm, $serializer, $ev)
{
$model = Helpers::get_module($module);
$id = $ev['id'];
unset($ev['id']);
$qb = $dm->createQueryBuilder($model)
// Find the job
->findAndUpdate()
->field('id')->equals($id);
foreach ($ev as $k => $val) {
$qb = $qb->field($k)->set($val);
}
$qb->getQuery()->execute();
return true;
}
public static function findModelBy($dm, $module, $vals)
{
$model = Helpers::get_module($module);
return $dm->getRepository($model)->findOneBy($vals);
}
public static function CheckAddModel($dm, $module, $value, $filters, $serializer)
{
$model = Helpers::get_module($module);
$db_value = self::findModelBy($dm, $module, $filters);
$_id = self::AddOrUpdate($model, $dm, $serializer, (array) $value, $db_value);
return $db_value;
}
public static function UpdateModelWithValue($dm, $value, $model, $val, $serializer)
{
$db_value = $serializer->deserialize(json_encode($value), $model, 'json', [...Variables::DESERIALZER_OPTIONS, ObjectNormalizer::DEEP_OBJECT_TO_POPULATE => true, 'object_to_populate' => clone $val, 'dm' => $dm, 'serializer' => $serializer, 'creating' => false]);
$dm->persist($db_value);
$dm->flush();
return $db_value;
}
public static function UpdateModel($dm, $repo, $model, $value, $vals, $serializer)
{
$val = $repo->findOneBy($vals);
if ($val) {
return self::UpdateModelWithValue($dm, $value, $model, $val, $serializer);
}
return null;
}
public static function checkUniq($collection, $key, $value, $id, $extra = [])
{
$trimmed = trim(preg_replace('/\s+/', ' ', $value));
$val = new \MongoDB\BSON\Regex('^'.$trimmed.'$', 'i');
$exists = $collection->findOneBy([$key => $val, ...$extra]);
if ($exists && $exists->id != $id) {
return "{$key} at {$value} is already Exist";
}
}
public static function FetchWithAggregation($dm, $module, $filters = [], $aggs = [], $props = [])
{
$model = Helpers::get_module($module);
$cs = Helpers::get_module_config($module);
$query = $dm->createAggregationBuilder($model);
if ($props['hydrate'] ?? false) {
$query = $query->hydrate($model);
}
$class = new $model();
$out = Helpers::getModelFilter($cs->filters ?? []);
$query = $query->match();
if (count($out) > 0) {
$query = $query->addAnd($out);
}
$pre_filter = $props['pre_filter'] ?? [];
foreach ($pre_filter as $agg => $val) {
$query = AggregateFuns::{$val['agg'] ?? $agg}($query, array_diff_key($val, ['agg' => null]));
$query = $query->match();
}
if (count($filters) > 0) {
$query = $query->addAnd($filters);
} else {
$query = $query->addAnd(['id' => ['$exists' => true]]);
}
foreach ($aggs as $agg => $val) {
$query = AggregateFuns::{$val['agg'] ?? $agg}($query, array_diff_key($val, ['agg' => null]));
}
if ($props['agg'] ?? false) {
$m_aggs = $cs->aggregation[$props['agg']] ?? [];
foreach ($m_aggs as $agg => $val) {
$query = AggregateFuns::{$val['agg'] ?? $agg}($query, array_diff_key($val, ['agg' => null]));
}
}
if ($props['limit'] ?? false) {
$query = $query->limit($props['limit']);
}
return $query->execute();
}
public static function RemoveAC($x)
{
$x['updated_at'] = new \MongoDB\BSON\UTCDateTime();
if ('create' == $x['ac']) {
$x['created_at'] = $x['updated_at'];
}
unset($x['ac']);
unset($x['md']);
return $x;
}
public static function fetchWithKeys($dm, $filters, $keys, $module = 'collect__payment', $aggs = [], $props = [])
{
$data = self::FetchWithAggregation($dm, $module, $filters, $aggs, $props);
return Main::multiKeys(['levels' => $keys], $data, []);
}
public static function fetchWithBuildIds($dm, $filters, $keys, $module = 'collect__payment', $aggs = [], $props = [])
{
$data = self::FetchWithAggregation($dm, $module, $filters, $aggs, $props);
return Main::buildIdKeys(['levels' => $keys], $data, []);
}
public static function bulkDataInsert($dm, $data, $serializer = null, $params = [])
{
$total = array_sum(array_map(fn ($x) => count($x), $data));
$count = $params['count'] ?? 2000;
if ($params['updateProgress'] ?? false) {
$params['updateProgress'](['progress' => 1, 'status' => 'start processing']);
}
$inserted = 0;
foreach ($data as $module => $mds) {
$model = Helpers::get_module($module);
$updated = array_map([self::class, 'RemoveAC'], array_filter($mds, fn ($x) => 'update' == $x['ac'] || 'create' == $x['ac']));
if ($params['updateProgress'] ?? false) {
$params['updateProgress'](['status' => "update $module"]);
}
$update_count = count($updated);
if ($update_count > 0) {
$collection = $dm->getDocumentCollection($model);
$updates = array_chunk($updated, $count);
foreach ($updates as $update) {
$end = count($update);
$d_updates = array_map(function ($x) {
return [
'updateOne' => [
['_id' => $x['_id']],
['$set' => $x],
['upsert' => true],
],
];
}, $update);
$collection->bulkWrite($d_updates);
$inserted += $end;
if ($params['updateProgress'] ?? false) {
$params['updateProgress'](['progress' => $inserted / $total * 100]);
}
}
if ($params['updateProgress'] ?? false) {
$params['updateProgress'](['progress' => $inserted / $total * 100]);
}
}
$updatedMany = array_map([self::class, 'RemoveAC'], array_filter($mds, fn ($x) => 'update_many' == $x['ac']));
$update_count = count($updatedMany);
if ($update_count > 0) {
$collection = $dm->getDocumentCollection($model);
$updatesMany = array_chunk($updatedMany, $count);
foreach ($updatesMany as $updateMany) {
$end = count($updateMany);
$d_updates = array_map(function ($x) {
$op = $x['op'] ?? '$set';
return [
'updateMany' => [
$x['filter'],
[[$op => $x['update']]],
],
];
}, $updateMany);
$res = $collection->bulkWrite($d_updates);
$inserted += $end;
if ($params['updateProgress'] ?? false) {
$params['updateProgress'](['progress' => $inserted / $total * 100]);
}
}
if ($params['updateProgress'] ?? false) {
$params['updateProgress'](['progress' => $inserted / $total * 100]);
}
}
}
}
public static function updateOne($dm, $module, $setting)
{
['where' => $where, 'update' => $update] = $setting;
$model = Helpers::get_module($module);
$collection = $dm->getDocumentCollection($model);
$collection->updateOne(
$where,
$update,
['upsert' => true]
);
}
public static function updateMany($dm, $module, $setting)
{
['where' => $where, 'update' => $update] = $setting;
$model = Helpers::get_module($module);
$collection = $dm->getDocumentCollection($model);
$res = $collection->updateMany(
$where,
$update
);
return ['matched'=>$res->getMatchedCount(), 'modified'=>$res->getModifiedCount()];
}
public static function getOneBy($dm, $model, $where)
{
$md = Helpers::get_module($model);
return $dm->getRepository($md)->findOneBy($where);
}
public static function getList($dm, $model, $where)
{
$md = Helpers::get_module($model);
return $dm->getRepository($md)->findBy($where);
}
public static function AddArray($dm, $serializer, $model, $arr)
{
$values = $serializer->deserialize(json_encode($arr), $model.'[]', 'json');
$ids = [];
foreach ($values as $key => $value) {
// code...
$dm->persist($value);
$dm->flush();
$ids[$key] = $value->getId();
}
return $dm->getRepository($model)->findBy(['id' => ['$in' => $ids]]);
}
public static function ModelCount($dm, $module, $where)
{
$m_model = strtolower($module);
$model = Helpers::get_module($m_model);
if ($model) {
$qb = $dm->createQueryBuilder($model);
if ($where) {
$qb = $qb->addAnd($where);
}
return $qb->getQuery()->execute()->count();
}
}
public static function MultiDeleteModule($dm, $module, $where)
{
$m_model = strtolower($module);
$model = Helpers::get_module($m_model);
if ($model) {
$qb = $dm->createQueryBuilder($model);
$qb = $qb->remove();
if ($where) {
$qb = $qb->addAnd($where);
}
$qb->getQuery()->execute();
$dm->clear();
return true;
}
}
}