diff --git a/blocks/ORB/View.pm b/blocks/ORB/View.pm index 0fea3cb..bad43a8 100644 --- a/blocks/ORB/View.pm +++ b/blocks/ORB/View.pm @@ -23,6 +23,7 @@ use strict; use parent qw(ORB); # This class extends the ORB block class use experimental qw(smartmatch); use Regexp::Common qw(URI); +use DateTime; use v5.14; ## @method private $ _resolve_recipe_name($rid) @@ -101,6 +102,49 @@ sub _generate_tags { } +## @method private $ _generate_history($recipeid, $originalid) +# Generate the history list for the recipe. If there is only one +# version of the recipe (the current version), this returns an +# empty string. +# +# @param recipeid The ID of the current recipe. +# @param originalid The original ID of the recipe, undef for +# recipes with no history. +# @return A string containing the history html. +sub _generate_history { + my $self = shift; + my $recipeid = shift; + my $originalid = shift; + + my $histdata = $self -> {"system"} -> {"recipe"} -> get_history($recipeid, $originalid // $recipeid); + + my @rows = (); + foreach my $row (@{$histdata}) { + my $url = $self -> build_url(block => "view", + pathinfo => [ $row -> {"id"} ]); + + my $date = DateTime -> from_epoch(epoch => $row -> {"created"}, + time_zone => $self -> {"settings"} -> {"config"} -> {"time_zone"} // "Europe/London" ); + + my $template = ($row -> {"id"} == $recipeid) ? "view/history-nolink.tem" : "view/history-item.tem"; + + push(@rows, $self -> {"template"} -> load_template($template, + { + "%(view-url)s" => $url, + "%(name)s" => $row -> {"name"}, + "%(created)s" => $date -> strftime($self -> {"timefmt"}) + })); + } + return "" + unless(scalar(@rows) > 1); + + return $self -> {"template"} -> load_template("view/history.tem", + { + "%(recipes)s" => join("", @rows) + }); +} + + ## @method private $ _convert_source($source) # Replace all URLs in the specified source string with clickable links. # @@ -135,6 +179,9 @@ sub _generate_view { # Try to fetch the data. my $recipe = $self -> {"system"} -> {"recipe"} -> get_recipe($rid); + # And some past, if it's there + my $history = $self -> _generate_history($recipe -> {"id"}, $recipe -> {"original_id"}); + # Stop here if there's no recipe data available... return $self -> _fatal_error("{L_VIEW_ERROR_NORECIPE}") unless($recipe && $recipe -> {"id"}); @@ -185,6 +232,7 @@ sub _generate_view { "%(ingredients)s" => $ingreds, "%(method)s" => $recipe -> {"method"}, "%(notes)s" => $recipe -> {"notes"}, + "%(history)s" => $history, "%(controls)s" => $controls }); diff --git a/lang/en/view.lang b/lang/en/view.lang index 2d7c6e1..a8d456b 100644 --- a/lang/en/view.lang +++ b/lang/en/view.lang @@ -14,6 +14,8 @@ VIEW_TAGS = Tags VIEW_INGREDIENTS = Ingredients VIEW_METHOD = Method VIEW_NOTES = Notes +VIEW_HISTORY = History +VIEW_THISVERSION = This version VIEW_EDIT = Edit VIEW_CLONE = Clone diff --git a/modules/ORB.pm b/modules/ORB.pm index f6c10c8..daadffb 100755 --- a/modules/ORB.pm +++ b/modules/ORB.pm @@ -54,7 +54,8 @@ sub DateTime::TO_JSON { sub new { my $invocant = shift; my $class = ref($invocant) || $invocant; - my $self = $class -> SUPER::new(entitymap => { '–' => '-', + my $self = $class -> SUPER::new(timefmt => '%a, %d %b %Y %H:%M', + entitymap => { '–' => '-', '—' => '-', '’' => "'", '‘' => "'", diff --git a/modules/ORB/System/Recipe.pm b/modules/ORB/System/Recipe.pm index 33c698f..dd15f62 100644 --- a/modules/ORB/System/Recipe.pm +++ b/modules/ORB/System/Recipe.pm @@ -221,6 +221,9 @@ sub edit { $self -> {"logger"} -> log("recipe.edit", $args -> {"creator_id"}, "unknown", "Renumbered ".$args -> {"id"}." as $renumbered"); + # Clear the original ID for the master. + $args -> {"origid"} = undef; + # Create the new recipe at the old ID $self -> create($args) or return undef; @@ -418,6 +421,30 @@ sub get_recipe { } +## @method $ get_history($recipeid, $originalid) +# Fetch the history for the specified recipe. +# +# @param recipeid The ID of the recipe +# @param originalid The ID of the original recipe +# @return A reference to an array of recipe hashes. +sub get_history { + my $self = shift; + my $recipeid = shift; + my $originalid = shift; + + my $recipes = $self -> {"dbh"} -> prepare("SELECT `id`, `name`, `created` + FROM `".$self -> {"settings"} -> {"database"} -> {"recipes"}."` AS `r` + WHERE `id` = ? + OR `id` = ? + OR `original_id` = ? + ORDER BY `created` DESC"); + $recipes -> execute($recipeid, $originalid, $originalid) + or return $self -> self_error("Unable to perform recipe history lookup: ".$self -> {"dbh"} -> errstr); + + return $recipes -> fetchall_arrayref({}); +} + + ## @method $ load_recipe_relations($recipe) # Fetch the supporting information for the specified recipe. This will load # additional information about the recipe (ingredients, tags, ...) into the diff --git a/templates/default/view/content.tem b/templates/default/view/content.tem index a2e69ec..eeaa9c8 100644 --- a/templates/default/view/content.tem +++ b/templates/default/view/content.tem @@ -56,5 +56,6 @@