/** * @param \simple_html_dom_node $node */ private function emptyNodeContent(\simple_html_dom_node $node) { $node->innertext = ''; foreach ($node->children() as $child) { $this->emptyNodeContent($child); } }
/** * 取得欄位資料. * * @param \simple_html_dom_node $row * @param string $department * @return array */ protected function getColumns($row, $department) { static $name = ['domain', 'grade', 'code', 'class', 'name', 'professors', 'hours', 'credit', 'type', 'time', 'location', 'limit']; // I001:通識 $i = 'I001' === $department ? 0 : 1; foreach ($row->children() as $node) { if ($i >= 12) { break; } $result[$name[$i++]] = trim($node->plaintext); } return $result ?? []; }
/** * @param Operation[]|array $operations * @param \simple_html_dom_node $oldListNode * @param \simple_html_dom_node $newListNode * * @return string */ protected function processOperations($operations, $oldListNode, $newListNode) { $output = ''; $indexInOld = 0; $indexInNew = 0; $lastOperation = null; foreach ($operations as $operation) { $replaced = false; while ($operation->startInOld > ($operation->action === Operation::ADDED ? $indexInOld : $indexInOld + 1)) { $li = $oldListNode->children($indexInOld); $matchingLi = null; if ($operation->startInNew > ($operation->action === Operation::DELETED ? $indexInNew : $indexInNew + 1)) { $matchingLi = $newListNode->children($indexInNew); } if (null !== $matchingLi) { $htmlDiff = HtmlDiff::create($li->innertext, $matchingLi->innertext, $this->config); $li->innertext = $htmlDiff->build(); $indexInNew++; } $class = self::CLASS_LIST_ITEM_NONE; if ($lastOperation === Operation::DELETED && !$replaced) { $class = self::CLASS_LIST_ITEM_CHANGED; $replaced = true; } $li->setAttribute('class', trim($li->getAttribute('class') . ' ' . $class)); $output .= $li->outertext; $indexInOld++; } switch ($operation->action) { case Operation::ADDED: for ($i = $operation->startInNew; $i <= $operation->endInNew; $i++) { $output .= $this->addListItem($newListNode->children($i - 1)); } $indexInNew = $operation->endInNew; break; case Operation::DELETED: for ($i = $operation->startInOld; $i <= $operation->endInOld; $i++) { $output .= $this->deleteListItem($oldListNode->children($i - 1)); } $indexInOld = $operation->endInOld; break; case Operation::CHANGED: $changeDelta = 0; for ($i = $operation->startInOld; $i <= $operation->endInOld; $i++) { $output .= $this->deleteListItem($oldListNode->children($i - 1)); $changeDelta--; } for ($i = $operation->startInNew; $i <= $operation->endInNew; $i++) { $output .= $this->addListItem($newListNode->children($i - 1), $changeDelta < 0); $changeDelta++; } $indexInOld = $operation->endInOld; $indexInNew = $operation->endInNew; break; } $lastOperation = $operation->action; } $oldCount = count($oldListNode->children()); $newCount = count($newListNode->children()); while ($indexInOld < $oldCount) { $li = $oldListNode->children($indexInOld); $matchingLi = null; if ($indexInNew < $newCount) { $matchingLi = $newListNode->children($indexInNew); } if (null !== $matchingLi) { $htmlDiff = HtmlDiff::create($li->innertext(), $matchingLi->innertext(), $this->config); $li->innertext = $htmlDiff->build(); $indexInNew++; } $class = self::CLASS_LIST_ITEM_NONE; if ($lastOperation === Operation::DELETED) { $class = self::CLASS_LIST_ITEM_CHANGED; } $li->setAttribute('class', trim($li->getAttribute('class') . ' ' . $class)); $output .= $li->outertext; $indexInOld++; } $newListNode->innertext = $output; $newListNode->setAttribute('class', trim($newListNode->getAttribute('class') . ' diff-list')); return $newListNode->outertext; }