Sorting Twig array by day of given date - sorting

I'd like to sort an array (nextbirthdays) by a date value which is given. Unlike just ordering the date itself, I'd like to sort by the day given. In this case I'd like to display the birthdays of users. The dataset given only contains users with their birthday of today plus 7 days.
the dataset itself could look something like this:
Birthday | Username
--------------+-----------
01. Apr 1953 | User 1
04. Apr 1970 | User 2
02. Apr 1992 | User 3
02. Apr 2002 | User 4
01. Apr 1993 | User 5
When using nextbirthdays|sort twig correctly sorts the dates (by newest to olderst or the other way around) but I'd like to sort by the actual day, then month, then year of the date.
Birthday | Username
--------------+-----------
01. Apr 1993 | User 5
01. Apr 1953 | User 1
02. Apr 2002 | User 4
02. Apr 1992 | User 3
04. Apr 1970 | User 2
Original Code:
<ul>
{% for nextbd in nextbirthdays %}
<li><span class="text-muted mr-3">{{ nextbd.birthday|date("d. M Y") }}: </span>
{% if nextbd.birthday|date("d.m") == "now"|date("d.m") %}
<b>{{ nextbd.firstname }} {{ nextbd.lastname }}</b>
{% else %}
{{ nextbd.firstname }} {{ nextbd.lastname }}
{% endif %}
{% endfor %}
</ul>
Sort & Map:
When trying to adapt the sort function from twig using the statement below the birthdays don't show up anymore.
{% for nextbd in nextbirthdays|sort((a, b) => a.birthday <=> b.birthday)|column('birthday') %}
<!-- rest of the code is unchanged -->
{% endfor %}

You do have two issues in your code:
|column('birthday'): using this filter, you'll limit your array to the column birthday only, so you won't get the first or last name anymore.
Your requirement is more complex than what you think it is:
01. Apr sorted before 02. Apr means your are doing an ascending sort on the day and month
01. Apr 1993 sorted before 01. Apr 1953 means you are doing a descending sorting on the year
So, your condition should be:
a.birthday|date('dm') > b.birthday|date('dm') or (a.birthday|date('dm') == b.birthday|date('dm') and a.birthday|date('Y') < b.birthday|date('Y'))
Giving a for loop:
{% for nextbd in nextbirthdays|sort((a, b) => a.birthday|date('dm') > b.birthday|date('dm') or (a.birthday|date('dm') == b.birthday|date('dm') and a.birthday|date('Y') < b.birthday|date('Y'))) %}
{# rest of the code is unchanged #}
{% endfor %}
This can be tested here: https://twigfiddle.com/of3cbi

Related

Display data on my codeigniter view page from the same database table but with different categories (using the same model and controller)

All of this has worked fine for a year, however now I have to separate my goals on the same page between 2020 and 2021. I have "goal_year" as my column within the "goals_table" database table.
I tried to create 2 separate cells where the code pulls in goals for 2020 and goals for 2021 but it makes the entire page show blank.
I'm trying to do this without creating a separate model and controller file.
DATABASE
id | district | goal_year | goal_af_am_msm | goal_b | goal_c
---------------------------------------------------------------
1 | macon | 2020 | 456 | 87 | 234
2 | cobb | 2020 | 987 | 34 | 762
3 | macon | 2021 | 432 | 67 | 819
4 | fulton | 2021 | 843 | 21 | 236
Here's my code:
MODEL
function _goal()
{
$this->db->where('district', 'macon');
$query = $this->db->get('goals_table');
return $query->row();
}
CONTROLLER
public function index()
{
$data['_goal_data'] = $this->Macon_model->_goal(); // GOALS
$this->template->load('admin', 'default', 'macon', $data);
}
VIEW
<td>
<?php echo $_goal_data->goal_af_am_msm; ?> <!-- ENTERED GOALS -->
</td>
ALTERNATE VIEWS THAT I TRIED
1).
<td>
<?php echo $_goal_data->goal_af_am_msm->where('goal_year','2020'); ?>
<!-- Shows entire page blank -->
</td>
2).
<td>
<?php if($_goal_data->goal_year == '2020') echo $_goal_data->goal_af_am_msm ; ?>
<!-- Shows 2020 GOALS but show blank for 2021 -->
</td>
3).
<td>
<?php echo $_goal_data->goal_year == '2020' ? $_goal_data->goal_af_am_msm : ''; ?>
<!-- Shows 2020 GOALS but show blank for 2021 -->
</td>
So I kept playing around with it and I got it figured out. I ended up having to change my model from
return $query->row();
to
return $query->result();
Then I had to update my view file to
<?php foreach($_goal_data as $macon_data) : ?>
<?php if($macon_data->goal_year == '2020') echo $macon_data->goal_af_am_msm; ?>
<?php endforeach; ?>

Group select options if description is the same

So I have a select that the options are froma laravel Foreach
#foreach($courseMonth as $cm)->groupBy('description');
<optgroup label="{{ nameMonth($cm->month) }}">
#foreach($days as $date)
#if(date('m', strtotime($date['date'])) == $cm->month)
<option value="{{ date('d/m/Y', strtotime($date['date'])) ." - ". $date['hours'] }}">{{ $date['description'] . ' - ' . date('d/m/Y', strtotime($date['date'])) . ' - ' . $date['hours'] . ' ('. $date['total'] . 'h)'}}</option>
#endif
#endforeach
</optgroup>
<?php $i++;?>
#endforeach
This is the options. And I want if $date['description'] is the same in two options, to combine both options. More detailed, if three options have their description as "Work", to combine all of the options.
I've tried a groupby in front of the foreach
#foreach($courseMonth as $cm)->groupBy('description');
But this didn't do anything. The table for the options only has one row (ex: One row has only one description but it can have multiple day options in the select) so I need to group those only when there is the same description in two options.
Table structure:
-----------------------------------------------
| id | description | date | hours | total |
|---------------------------------------------|
| 4 | work |2019-23-4 | 14h | 6h |
| 5 | work |2019-23-5 | 13h | 5h |
| 6 | school |2019-23-5 | 13h | 5h |
-----------------------------------------------
So the first two would appear in the same option and the last one as the second option of the select.

Sort Logfile for unqiue SRC + DST IPs

I would like to sort my Logfile (~5 GB) for unique connection events.
Unique (SRC_IP + DST_IP) only - but with timestamps and the other informations.
Example:
1 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.2" dstip="10.10.10.2"...
2 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.1" dstip="10.10.10.2"...
3 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.2" dstip="10.10.10.1"...
4 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.2" dstip="10.10.10.2"...
5 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.2" dstip="10.10.10.2"...
The output events should be:
1 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.2" dstip="10.10.10.2"...
2 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.1" dstip="10.10.10.2"...
3 Feb 5 14:59:00 initf="eth0" outift="eth1" srcip="192.168.0.2" dstip="10.10.10.1"...
because the combination of src + dst IP is unique. I tried this with sort -uk column but it doesn't work as intended. Also the column of src + dst IP are not consistent. It switches sometimes, because depending on the out-interface, the dstmac is submitted or not.
Maybe an AWK script could do the trick ?
EDIT
Since Karakfa made a good suggestion, solving this with awk - I am currently trying to change [$7,$8] into a regex
awk '!a[regexpression for src ip, regexpression for dst ip]++' file
so it won't matter if the position of dst and src IP changes. #Ed Morton
assuming no spaces in the first 8 field values, this will give you the first appearance of the combination of the key.
$ awk '!a[$7,$8]++' file
This doesn't require sorted input (and won't change the order itself), you can pipe this into sort with your desired order.
If the field order is not fixed, you can do something like this:
$ awk '{for(i=1;i<=NF;i++) if($i~/^srcip=/) s=$i; else if($i~/^dstip=/) d=$i}
!a[s,d]++;
{s=d=""}' file
Note that records with missing fields will be grouped as well. You may want to print all of those individually.

Laravel 5.4 pluck, where

I'm working on an assignment system for radio newscasts. Trying to return a view of all assignments for a particular newscast, and I'm stymied.
Tables
users table
id | name
---|-------
1 | Admin
2 | Susan
3 | Ed
4 | Jen
newscasts table
id | forStation_id | name
---|---------------|-----
1 | 1 | AM
2 | 1 | PM
3 | 2 | Sports
stations table
id | calls
---| -----
1 | JNDV
2 | YXWQ
assignments table
id | anchorId | newscastId | startDate | endDate | isTemp
---|----------|------------|-------------|-------------|--------
1 | 2 | 1 | 01 May 2017 | 31 Dec 2999 |
2 | 3 | 1 | 02 May 2017 | 06 May 2017 | True
3 | 4 | 2 | 01 Apr 2017 | 31 Dec 2999 |
4 | 3 | 3 | 01 Apr 2017 | 28 Apr 2017 |
(part of) Assignment model
public function anchor()
{
return $this->belongsTo(User::class, 'anchor_id')->withTrashed();
}
public function cast()
{
return $this->belongsTo(Newscast::class, 'cast_id')->withTrashed();
}
(part of) Newscast model
public function for_station()
{
return $this->belongsTo(Station::class, 'for_station_id')->withTrashed();
}
function getNameInputStationAttribute() {
return $this->for_station->calls . "-" . $this->name_input;
}
(part of) Assignment controller
/**
* Display all Assignments for one input name.
*
* #param int $name
* #return \Illuminate\Http\Response
*/
public function showAssignmentsByCastName($castName)
{
if (! Gate::allows('assignment_view')) {
return abort(403);
}
$relations = [
'anchors' => \App\User::get()->pluck('name', 'id'),
'casts' => \App\Newscast::with('for_station')->get()->pluck('name_input_station', 'id'),
'assignments' => \App\Assignment::with('cast')->get(),
];
dump($relations);
return view('assign.list', compact('castName') +$relations);
}
As I'd expect, this code returns the full collection of assignments.
Output
Anchor | Cast Name | Start Date | End Date
---------|-------------|-------------|-------------
Susan | JNDV-AM | 01 May 2017 | 31 Dec 2999
Ed | JNDV-AM | 02 May 2017 | 06 May 2017
Jen | JNDV-PM | 01 Apr 2017 | 31 Dec 2999
Ed | YXWQ-Sports | 01 Apr 2017 | 28 Apr 2017
I've tried several ways to limit the assignments to only one newscastId, thus far without success.
Desired Output for /assignment/list/JNDV-AM on 01 May 2017
Anchor | Cast Name | Start Date | End Date
---------|-------------|-------------|-------------
Susan | JNDV-AM | 01 May 2017 | 31 Dec 2999
Ed | JNDV-AM | 02 May 2017 | 06 May 2017
The shorter-term assignment is a temporary one (isTemp=True). During the days it is valid, it should be listed on top.
Desired Output for /assignment/list/JNDV-AM on 02 May 2017 through 06 May 2017
Anchor | Cast Name | Start Date | End Date
---------|-------------|-------------|-------------
Ed | JNDV-AM | 02 May 2017 | 06 May 2017
Susan | JNDV-AM | 01 May 2017 | 31 Dec 2999
I'm modifying code produced by an admin panel generator tool. It seems to me that querying for all users and all casts is not the most efficient way to go about it. I'd think, since I'm looking for only the current & future assignments for one newscast, that the anchors and casts relations should be filtered.
Basic question
What changes should I make to
'assignments' => \App\Assignment::with('cast')->get(),
to get only the assignments for JNDV-AM (newscastId = 1)?
Advanced Question
How do you recommend changing relations to return only the current and future assignments for JNDV-AM, today's assignment first, with the fewest queries possible?
You can pass a function into your with statement:
'assignments' => \App\Assignment::with(['cast' => function ($query) {
$query->where('newscastId', '=', 1);
}])->get()
Here is the working code I came up with:
(part of) Assignments controller
public function showAssignmentsByCastName($calls, $name_input)
{
if (!Gate::allows('assignment_view')) {
return abort(403);
}
$castName = strtoupper($calls). "-" . $name_input;
$station_id = \App\Station::where('calls', $calls)->get();
$station = \App\Station::findOrFail($station_id);
$cast_id = \App\Newscast::where([
['for_station_id', $station->id],
['name_input', $name_input]
])->get();
$cast = \App\Newscast::findOrFail($cast_id);
$relations = [
'anchors' => \App\User::get()->pluck('name', 'id'),
'casts' => \App\Newscast::where('cast_id', $cast->id),
'assignments' => \App\Assignment::where('cast_id', $cast->id)->get(),
];
return view('assign.list', compact('castName') + $relations);
}
web route
Route::get('assign/{calls}-{name_input}', 'AssignmentsController#showAssignmentsByCastName')->name('assign.list');

Get today's date in Jekyll with Liquid markup

This (should) be easy, I think, but I'm unable to get today's date to show in a Jekyll page using Liquid markup. According to the documentation, I should be able to do this to get this date's year:
{{ 'now' | date: "%Y" }}
But all that gets rendered is the string now, not any formatted date. What am I doing wrong?
It didn't work for me either. It appears you've hit a current bug in the Ruby 1.9.3 support. There is a pull request that fixes the bug, but it's not incorporated yet. A workaround is listed, perhaps it will work for you:
{{ site.time | date: '%y' }}
To get the whole year, for example "2015", from the site.time, you can either use:
{{ site.time | date: '%Y' }}
# OR
20{{ site.time | date: '%y' }}
To just get the last 2 digits from the year 2015, this will just output "15":
{{ site.time | date: '%y' }}
Perhaps the question title is misleading but I actually wanted today's date and not the year. This works for me:
{{ site.time | date: '%B %d, %Y' }}
Today it produced: January 04, 2019
{{ site.time }} represent the time the site did get updated it is a fixed date not a dynamic one.
Such request require Javascript with Date.getTime() or Date.now() example:
<script>document.write(Math.round(Date.now() / (365 * 24 * 60 * 60 * 1000) + 1970 - 1));</script>

Resources