public function format_change($history, $change, $options, $table_options) { $html = ''; $classes = []; if (empty($table_options['never_obsolete'][$change->column_name]) && $change->is_obsolete()) { $classes[] = 'obsolete'; } $added = '<span class="added">+</span>'; $removed = '<span class="removed">-</span>'; $sort_key = $change->remote_id; $primary_order = 1; switch ($change->table_name) { case 'posts': switch ($change->column_name) { case 'rating': $html .= '<span class="changed-post-rating">rating:'; $html .= $change->value; if ($change->previous) { $html .= '←'; $html .= $change->previous->value; } $html .= '</span>'; break; case 'parent_id': $html .= 'parent:'; if ($change->value) { $new = Post::where('id = ?', $change->value)->first(); if ($new) { $html .= $this->linkTo($new->id, ['post#show', 'id' => $new->id]); } else { $html .= $change->value; } } else { $html .= 'none'; } if ($change->previous) { $html .= '←'; if ($change->previous->value) { $old = Post::where('id = ?', $change->previous->value)->first(); if ($old) { $html .= $this->linkTo($old->id, ['post#show', 'id' => $old->id]); } else { $html .= $change->previous->value; } } else { $html .= 'none'; } } break; case 'source': if ($change->previous) { $html .= sprintf("source changed from <span class='name-change'>%s</span> to <span class='name-change'>%s</span>", $this->source_link($change->previous->value, false), $this->source_link($change->value, false)); } else { $html .= sprintf("source: <span class='name-change'>%s</span>", $this->source_link($change->value, false)); } break; case 'frames_pending': $html .= 'frames changed: ' . $this->h($change->value ?: '(none)'); break; case 'is_rating_locked': # Trueish: if a value equals true or 't' $html .= $change->value || $change->value == 't' ? $added : $removed; $html .= 'note-locked'; break; case 'is_shown_in_index': # Trueish $html .= $change->value || $change->value == 't' ? $added : $removed; $html .= 'shown'; break; case 'cached_tags': $previous = $change->previous; $changes = Post::tag_changes($change, $previous, $change->latest()); $list = []; $list[] = $this->tag_list($changes['added_tags'], ['obsolete' => $changes['obsolete_added_tags'], 'prefix' => '+', 'class' => 'added']); $list[] = $this->tag_list($changes['removed_tags'], ['obsolete' => $changes['obsolete_removed_tags'], 'prefix' => '-', 'class' => 'removed']); if (!empty($options['show_all_tags'])) { $list[] = $this->tag_list($changes['unchanged_tags'], ['prefix' => '', 'class' => 'unchanged']); } $html .= trim(implode(' ', $list)); break; } break; case 'pools': $primary_order = 0; switch ($change->column_name) { case 'name': if ($change->previous) { $html .= sprintf("name changed from <span class='name-change'>%s</span> to <span class='name-change'>%s</span>", $this->h($change->previous->value), $this->h($change->value)); } else { $html .= sprintf("name: <span class='name-change'>%s</span>", $this->h($change->value)); } break; case 'description': if ($change->value === '') { $html .= 'description removed'; } else { if (!$change->previous) { $html .= 'description: '; } elseif ($change->previous->value === '') { $html .= 'description added: '; } else { $html .= 'description changed: '; } # Show a diff if there's a previous description and it's not blank. Otherwise, # just show the new text. $show_diff = $change->previous && $change->previous->value !== ''; if ($show_diff) { $text = Moebooru\Diff::generate($change->previous->value, $change->value); } else { $text = $this->h($change->value); } # If there's only one line in the output, just show it inline. Otherwise, show it # as a separate block. $multiple_lines = is_int(strpos($text, '<br>')) || is_int(strpos($text, '<br />')); $show_in_detail = !empty($options['specific_history']) || !empty($options['specific_object']); if (!$multiple_lines) { $display = $text; } elseif ($show_diff) { $display = "<div class='diff text-block'>{$text}</div>"; } else { $display = "<div class='initial-diff text-block'>{$text}</div>"; } if ($multiple_lines && !$show_in_detail) { $html .= "<a onclick='\$(this).hide(); \$(this).next().show()' href='#'>(show changes)</a><div style='display: none;'>{$display}</div>"; } else { $html .= $display; } } break; case 'is_public': # Trueish $html .= $change->value || $change->value == 't' ? $added : $removed; $html .= 'public'; break; case 'is_active': # Trueish $html .= $change->value || $change->value == 't' ? $added : $removed; $html .= 'active'; break; } break; case 'pools_posts': # Sort the output by the post id. $sort_key = $change->obj()->post->id; switch ($change->column_name) { case 'active': # Trueish $html .= $change->value || $change->value == 't' ? $added : $removed; $html .= $this->linkTo('post #' . $change->obj()->post_id, ['post#show', 'id' => $change->obj()->post_id]); break; case 'sequence': /** * MI: For some reason the sequence is shown in the first HistoryChange created, * while in Moebooru it doesn't. We will hide it here. */ if (!$change->previous) { return null; } $seq = 'order:' . $change->obj()->post_id . ':' . $change->value; $seq .= '←' . $change->previous->value; $html .= $this->linkTo($seq, ['post#show', 'id' => $change->obj()->post_id]); break; } break; case 'tags': switch ($change->column_name) { case 'tag_type': $html .= 'type:'; $tag_type = Tag::type_name_from_value($change->value); $html .= '<span class="tag-type-' . $tag_type . '">' . $tag_type . '</span>'; if ($change->previous) { $tag_type = Tag::type_name_from_value($change->previous->value); $html .= '←<span class="tag-type-' . $tag_type . '">' . $tag_type . '</span>'; } break; case 'is_ambiguous': # Trueish $html .= $change->value || $change->value == 't' ? $added : $removed; $html .= 'ambiguous'; break; } break; case 'notes': switch ($change->column_name) { case 'body': if ($change->previous) { $html .= sprintf("body changed from <span class='name-change'>%s</span> to <span class='name-change'>%s</span>", $this->h($change->previous->value), $this->h($change->value)); } else { $html .= sprintf("body: <span class='name-change'>%s</span>", $this->h($change->value)); } break; case 'x': case 'y': case 'width': case 'height': $html .= $change->column_name . ':' . $this->h($change->value); break; case 'is_active': # Trueish if ($change->value || $change->value == 't') { # Don't show the note initially being set to active. if (!$change->previous) { return null; } $html .= 'undeleted'; } else { $html .= 'deleted'; } } break; } $span = '<span class="' . implode(' ', $classes) . '">' . $html . '</span>'; return ['html' => $span, 'field' => $change->column_name, 'sort_key' => $sort_key]; }
public function diff($version) { if ($otherpage = self::find_page($this->title, $version)) { return Moebooru\Diff::generate($this->body, $otherpage->body); } }