ElementJsonGenerator.php 7.56 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
<?php

namespace Biopen\GeoDirectoryBundle\EventListener;

use Biopen\GeoDirectoryBundle\Document\Element;
use Biopen\GeoDirectoryBundle\Document\ModerationState;
use Biopen\GeoDirectoryBundle\Document\ElementStatus;

class ElementJsonGenerator
{
11 12
  protected $currElementChangeset;
  protected $config = null;
13
  protected $options = null;
14

15
  public function getConfig($dm)
16 17 18 19
  {
    if (!$this->config) $this->config = $dm->getRepository('BiopenCoreBundle:Configuration')->findConfiguration();
    return $this->config;
  }
20

21 22 23 24 25 26 27 28
  public function getOptions($dm)
  {
    // load all options so we don't need to do a query on each element being modified
    if (!$this->options) $this->options = $dm->getRepository('BiopenGeoDirectoryBundle:Option')->createQueryBuilder()
                                             ->select('name')->hydrate(false)->getQuery()->execute()->toArray();
    return $this->options;
  }

29
  public function preFlush(\Doctrine\ODM\MongoDB\Event\PreFlushEventArgs $eventArgs)
30
  {
31
    $dm = $eventArgs->getDocumentManager();
32
    $documentManaged = $dm->getUnitOfWork()->getIdentityMap();
33

34 35
    if (array_key_exists("Biopen\GeoDirectoryBundle\Document\Element", $documentManaged))
    {
36 37 38 39
      // dump("on pre flush, number of doc managed" . count($documentManaged["Biopen\GeoDirectoryBundle\Document\Element"]));
      // $uow = $dm->getUnitOfWork();
      // $uow->computeChangeSets();

40 41
      foreach ($documentManaged["Biopen\GeoDirectoryBundle\Document\Element"] as $key => $element)
      {
42 43 44 45 46
        if (!$element->getPreventJsonUpdate()) {
          $element->setPreventJsonUpdate(true); // ensure perofming serialization only once
          $element->checkForModerationStillNeeded();

          // if we want to update only some specific part of the Json object, user currElementChangeset and below method attrChanged
47 48 49
          // $this->currElementChangeset = array_keys($uow->getDocumentChangeSet($element));
          $this->updateJsonRepresentation($element, $dm);
        }
50 51 52 53
      }
    }
  }

54
  public function updateJsonRepresentation($element, $dm)
55 56
  {
    if (!$element->getGeo()) { return; }
57
    $config = $this->getConfig($dm);
58
    $options = $this->getOptions($dm);
59 60

    // -------------------- FULL JSON ----------------
61

62 63 64
    // BASIC FIELDS
    $baseJson = json_encode($element);
    $baseJson = substr($baseJson , 0, -1); // remove last '}'
65 66 67
    if ($element->getAddress())   $baseJson .= ', "address":'    . $element->getAddress()->toJson();
    if ($element->getOpenHours()) $baseJson .= ', "openHours": ' . $element->getOpenHours()->toJson();

68 69 70 71 72 73 74 75 76
    // CREATED AT, UPDATED AT
    $baseJson .= ', "createdAt":"'    . date_format($element->getCreatedAt(),"d/m/Y à H:i") . '"';
    $updatedAt = $element->getUpdatedAt() ? $element->getUpdatedAt() : $element->getCreatedAt();
    $updatedAtFormated = gettype($updatedAt) == "integer" ? date("d/m/Y à H:i", $updatedAt) : date_format($updatedAt,"d/m/Y à H:i");
    $baseJson .= ', "updatedAt":"'    . $updatedAtFormated . '"';

    // OPTIONS VALUES (= TAXONOMY)
    $sortedOptionsValues = $element->getSortedOptionsValues();
    $optValuesLength = count($sortedOptionsValues);
77 78
    $optionsString = '';
    $optionsFullJson = [];
79
    if ($sortedOptionsValues)
80
    {
81 82 83 84 85 86
      for ($i=0; $i < $optValuesLength; $i++) {
        $optionValue = $sortedOptionsValues[$i];
        $optionName = json_encode($options[$optionValue->getOptionId()]['name']);
        $optionsString .=  $optionName . ',';
        $optionsFullJson[] = $sortedOptionsValues[$i]->toJson($optionName);
      }
87
    }
88
    $optionsString = rtrim($optionsString, ',');
89
    $baseJson .= ',"categories": [' . $optionsString . '],';
90 91 92
    $element->setOptionsString($optionsString); // we also update optionsString attribute which is used in exporting from element admin list
    // Options values with description
    if (count($optionsFullJson)) $baseJson .= '"categoriesFull": [' . implode(",", $optionsFullJson) . '],';
93 94 95 96 97 98

    // CUSTOM DATA
    if ($element->getData())
        foreach ($element->getData() as $key => $value) {
            $baseJson .= '"'. $key .'": ' . json_encode($value) . ',';
        }
99

100 101 102
    // SPECIFIC DATA
    $baseJson .= $this->encodeArrayObjectToJson("stamps", $element->getStamps());
    $baseJson .= $this->encodeArrayObjectToJson("images", $element->getImages());
103
    $baseJson = rtrim($baseJson, ',');
104 105 106 107 108 109 110 111 112 113 114

    // MODIFIED ELEMENT (for pending modification)
    if ($element->getModifiedElement()) {
        $baseJson .= ', "modifiedElement": ' . $element->getModifiedElement()->getJson(true, false);
    }
    $baseJson .= '}';

    $element->setBaseJson($baseJson);


    // -------------------- PRIVATE JSON -------------------------
115
    $privateJson = '{';
116
    // status
117
    $privateJson .= '"status": ' . strval($element->getStatus()) . ',';
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
    $privateJson .= '"moderationState": ' . $element->getModerationState() . ',';
    // CUSTOM PRIVATE DATA
    foreach ($element->getPrivateData() as $key => $value) {
        $privateJson .= '"'. $key .'": ' . json_encode($value) . ',';
    }
    $privateJson = rtrim($privateJson, ',');
    $privateJson .= '}';
    $element->setPrivateJson($privateJson);


    // ---------------- ADMIN JSON = REPORTS & CONTRIBUTIONS ---------------------
    $adminJson = '{';
    if ($element->getStatus() != ElementStatus::ModifiedPendingVersion)
    {
        $adminJson .= $this->encodeArrayObjectToJson('reports', $element->getUnresolvedReports());
        $adminJson .= $this->encodeArrayObjectToJson('contributions', $element->getContributionsAndResolvedReports());
        if ($element->isPending()) {
            $adminJson .= $this->encodeArrayObjectToJson('votes', $element->getVotesArray());
            if ($element->getCurrContribution()) $adminJson .= '"pendingContribution":' . $element->getCurrContribution()->toJson();
        }
        $adminJson = rtrim($adminJson, ',');
    }
    $adminJson .= '}';
    $element->setAdminJson($adminJson);

    // -------------------- COMPACT JSON ----------------
144
    // [id, customData, latitude, longitude, status, moderationState]
145
    $compactFields = $config->getMarker()->getFieldsUsedByTemplate();
146 147 148 149
    $compactData = [];
    foreach ($compactFields as $field) $compactData[] = $element->getProperty($field);

    $compactJson = '["'.$element->id . '",' . json_encode($compactData) . ',';
150 151 152
    $compactJson.= $element->getGeo()->getLatitude() .','. $element->getGeo()->getLongitude() .', [';
    if ($sortedOptionsValues)
    {
153
        for ($i=0; $i < $optValuesLength; $i++) {
154 155 156 157 158 159 160
            $value = $sortedOptionsValues[$i];
            $compactJson .= $value->getOptionId();
            $compactJson .= ',';
        }
        $compactJson = rtrim($compactJson, ',');
    }
    $compactJson .= ']';
161
    if ($element->getStatus() <= 0 || $element->getModerationState() != 0) $compactJson .= ','. strval($element->getStatus());
162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
    if ($element->getModerationState() != 0) $compactJson .= ','. $element->getModerationState();
    $compactJson .= ']';
    $element->setCompactJson($compactJson);
  }

  // private function attrChanged($attrs)
  // {
  //   if (!$this->currElementChangeset) return true;
  //   foreach ($attrs as $attr) {
  //       if (in_array($attr, $this->currElementChangeset)) return true;
  //   }
  //   return false;
  // }

  private function encodeArrayObjectToJson($propertyName, $array)
  {
    if (!$array) return "";
    $array = is_array($array) ? $array : $array->toArray();
    if (count($array) == 0) return '';
    $result = '"'. $propertyName .'": [';
    foreach ($array as $key => $value) {
        $result .= $value->toJson();
        $result .= ',';
    }
    $result = rtrim($result, ',');
    $result .= '],';
    return $result;
  }
}