/**
  * @param $html string
  */
 public function fromHtml($html)
 {
     $this->paragraphs->exchangeArray(array());
     if (trim($html)) {
         $dom = new \DOMDocument();
         $dom->loadHTML(trim($html));
         /** @var \DOMElement $node */
         foreach ($dom->getElementsByTagName('p') as $node) {
             $this->inputSystem = $node->getAttribute('lang');
             $paragraph = new LexParagraph();
             foreach (explode(' ', $node->getAttribute('class')) as $classValue) {
                 if (StringUtil::startsWith($classValue, 'guid_')) {
                     $guid = substr($classValue, 5);
                     if ($guid) {
                         $paragraph->guid = $guid;
                     }
                 }
                 if (StringUtil::startsWith($classValue, 'styleName_')) {
                     $styleName = substr($classValue, 10);
                     if ($styleName) {
                         $paragraph->styleName = $styleName;
                     }
                 }
             }
             $content = LiftDecoder::sanitizeSpans($node, $this->inputSystem);
             if ($content) {
                 $paragraph->content = $content;
             }
             $this->paragraphs->append($paragraph);
         }
     }
 }
 /**
  * Reads the js_dependencies.json file and creates a structure for use in the controller above
  *
  * The format of a line in the JSON is expected to be:
  * "itemName": {"path": "folderPath"}
  *
  * Additional properties could be:
  * "jsFile" as a string or an array
  * "jsMinFile" as a string or an array
  *
  * if jsFile is absent, then "itemName" is used as the filename
  * if jsMinFile is absent, then jsFile or "itemName is used as the min filename
  *
  * @return array
  */
 protected function getAngularAppJsDependencies()
 {
     $jsonData = json_decode(file_get_contents(APPPATH . "js_dependencies.json"), true);
     $jsFilesToReturn = array();
     $jsMinFilesToReturn = array();
     foreach ($jsonData as $itemName => $properties) {
         $path = $properties["path"];
         // process regular JS files
         if (array_key_exists("jsFile", $properties)) {
             $jsFile = $properties["jsFile"];
             if (!is_array($jsFile)) {
                 $jsFile = [$jsFile];
             }
             foreach ($jsFile as $file) {
                 if (StringUtil::endsWith($file, '.js')) {
                     $jsFilesToReturn[] = "{$path}/{$file}";
                 } else {
                     $jsFilesToReturn[] = "{$path}/{$file}.js";
                 }
             }
         } else {
             $jsFilesToReturn[] = "{$path}/{$itemName}.js";
         }
         // process minified JS files
         if (array_key_exists("jsMinFile", $properties)) {
             $jsMinFile = $properties["jsMinFile"];
             if (!is_array($jsMinFile)) {
                 $jsMinFile = [$jsMinFile];
             }
             foreach ($jsMinFile as $file) {
                 if (StringUtil::endsWith($file, '.js')) {
                     $jsMinFilesToReturn[] = "{$path}/{$file}";
                 } else {
                     $jsMinFilesToReturn[] = "{$path}/{$file}.min.js";
                 }
             }
         } elseif (array_key_exists("jsFile", $properties)) {
             $jsMinFile = $properties["jsFile"];
             if (!is_array($jsMinFile)) {
                 $jsMinFile = [$jsMinFile];
             }
             foreach ($jsMinFile as $file) {
                 if (StringUtil::endsWith($file, '.js')) {
                     $jsMinFilesToReturn[] = "{$path}/{$file}";
                 } else {
                     $jsMinFilesToReturn[] = "{$path}/{$file}.min.js";
                 }
             }
         } else {
             $jsMinFilesToReturn[] = "{$path}/{$itemName}.min.js";
         }
     }
     return array("js" => $jsFilesToReturn, "min" => $jsMinFilesToReturn);
 }
 /**
  * @param ObjectForEncoding $model
  * @param LexConfigFieldList $config
  * @param int $multiParagraphCount
  * @param boolean $modelModified
  */
 private static function migrateMultiParagraphs($model, $config, &$multiParagraphCount, &$modelModified)
 {
     if (isset($model->customFields)) {
         foreach ($model->customFields as $fieldName => $customField) {
             if (is_a($customField, 'Api\\Model\\Languageforge\\Lexicon\\LexMultiText')) {
                 $isMultiParagraph = false;
                 $multiParagraph = new LexMultiParagraph();
                 foreach ($customField as $tag => $text) {
                     if (StringUtil::startsWith($text->value, '<p>')) {
                         $isMultiParagraph = true;
                         $multiParagraphCount++;
                         $multiParagraph->inputSystem = $tag;
                         $value = substr($text->value, 3);
                         if (StringUtil::endsWith($value, '</p>')) {
                             $value = substr($value, 0, -4);
                         }
                         foreach (explode('</p><p>', $value) as $content) {
                             $paragraph = new LexParagraph();
                             if ($content) {
                                 $paragraph->content = $content;
                             }
                             $multiParagraph->paragraphs->append($paragraph);
                         }
                     }
                 }
                 if ($isMultiParagraph) {
                     $modelModified = true;
                     $model->customFields[$fieldName] = $multiParagraph;
                     if (!is_a($config->fields[$fieldName], 'Api\\Model\\Languageforge\\Lexicon\\Config\\LexConfigMultiParagraph')) {
                         $multiParagraphConfig = new LexConfigMultiParagraph();
                         $multiParagraphConfig->label = $config->fields[$fieldName]->label;
                         $multiParagraphConfig->hideIfEmpty = $config->fields[$fieldName]->hideIfEmpty;
                         $config->fields[$fieldName] = $multiParagraphConfig;
                     }
                 }
             }
         }
     }
 }