Skip to content

Commit

Permalink
New blog post - scalar functions (#1174)
Browse files Browse the repository at this point in the history
  • Loading branch information
norberttech authored Aug 8, 2024
1 parent c80bad9 commit 3faf80c
Show file tree
Hide file tree
Showing 17 changed files with 484 additions and 156 deletions.
4 changes: 2 additions & 2 deletions src/core/etl/src/Flow/ETL/Function/ScalarFunctionChain.php
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,9 @@ public function plus(ScalarFunction $ref) : self
return new Plus($this, $ref);
}

public function power(ScalarFunction $ref) : self
public function power(ScalarFunction|int|float $value) : self
{
return new Power($this, $ref);
return new Power($this, $value instanceof ScalarFunction ? $value : lit($value));
}

public function regex(ScalarFunction $pattern, ?ScalarFunction $flags = null, ?ScalarFunction $offset = null) : self
Expand Down
30 changes: 30 additions & 0 deletions src/core/etl/tests/Flow/ETL/Tests/Unit/Function/PowerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Flow\ETL\Tests\Unit\Function;

use function Flow\ETL\DSL\{int_entry, lit, ref, str_entry};
use Flow\ETL\Row;
use PHPUnit\Framework\TestCase;

final class PowerTest extends TestCase
{
public function test_power_non_numeric_values() : void
{
self::assertNull(
ref('int')->power(lit('non numeric'))->eval(Row::create(int_entry('int', 10)))
);
self::assertNull(
ref('str')->power(lit(2))->eval(Row::create(str_entry('str', 'abc')))
);
}

public function test_power_two_numeric_values() : void
{
self::assertSame(
100,
ref('int')->power(lit(2))->eval(Row::create(int_entry('int', 10)))
);
}
}
32 changes: 32 additions & 0 deletions web/landing/assets/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,36 @@ a {

code {
font-size: 0.9em;
}

#blog-post {
@apply py-10 px-2 sm:px-4 mx-auto max-w-screen-xl;
}

#blog-post hr, p, pre, ul {
@apply mb-3;
}

#blog-post pre {
@apply rounded my-6 p-4 overflow-auto rounded border-gray border-2 relative shadow-2xl shadow-gray;
}

#blog-post pre code {
@apply !p-0 !bg-transparent
}

#blog-post h1 {
@apply font-bold text-4xl;
}

#blog-post ul {
@apply list-disc pl-6;
}

#blog-post h2 {
@apply font-bold text-2xl mt-4;
}

#blog-post hr {
@apply text-blue-100 my-4 border-t-2 rounded;
}
14 changes: 7 additions & 7 deletions web/landing/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions web/landing/src/Flow/Website/Blog/Post.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace Flow\Website\Blog;

final class Post
{
public function __construct(
public readonly string $title,
public readonly string $description,
public readonly \DateTimeImmutable $date,
public readonly string $slug
) {
}

public static function fromArray(array $data) : self
{
return new self(
$data['title'],
$data['description'],
new \DateTimeImmutable($data['date']),
$data['slug']
);
}
}
46 changes: 46 additions & 0 deletions web/landing/src/Flow/Website/Blog/Posts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Flow\Website\Blog;

final class Posts
{
private array $posts = [
[
'title' => 'Building Custom Data Extractor - Flow PHP',
'description' => 'Learn how to extract data from Google Analytics API using Flow PHP but also how to build a custom data extractor.',
'date' => '2024-04-04',
'slug' => 'building-custom-extractor-google-analytics',
],
[
'title' => 'Scalar Functions',
'description' => 'Scalar functions are one of the most important building blocks of Flow. Learn how to build and use custom scalar functions in Flow PHP.',
'date' => '2024-08-08',
'slug' => 'scalar-functions',

],
];

/**
* @return array<Post>
*/
public function all() : array
{
return \array_map(
static fn (array $data) : Post => Post::fromArray($data),
\array_reverse($this->posts)
);
}

public function findByDateAndSlug(string $date, string $slug) : Post
{
foreach ($this->posts as $post) {
if ($post['date'] === $date && $post['slug'] === $slug) {
return Post::fromArray($post);
}
}

throw new \InvalidArgumentException('Post not found');
}
}
13 changes: 3 additions & 10 deletions web/landing/src/Flow/Website/Controller/BlogController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Flow\Website\Controller;

use Flow\Website\Blog\Posts;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
Expand All @@ -15,23 +16,15 @@ public function post(string $date, string $slug) : Response
{
return $this->render('blog/posts/' . $date . '/' . $slug . '/post.html.twig', [
'template_folder' => 'blog/posts/' . $date . '/' . $slug,
'post' => (new Posts())->findByDateAndSlug($date, $slug),
]);
}

#[Route('/blog', name: 'blog', priority: 100)]
public function posts() : Response
{
$posts = [
[
'title' => 'Building Custom Data Extractor - Flow PHP',
'description' => 'Learn how to extract data from Google Analytics API using Flow PHP but also how to build a custom data extractor.',
'date' => '2024-04-04',
'slug' => 'building-custom-extractor-google-analytics',
],
];

return $this->render('blog/posts.html.twig', [
'posts' => $posts,
'posts' => (new Posts())->all(),
]);
}
}
3 changes: 2 additions & 1 deletion web/landing/tailwind.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./assets/**/*.js",
"./assets/*.js",
"./assets/controllers/**/*.js",
"./templates/**/*.html.twig",
],
theme: {
Expand Down
13 changes: 13 additions & 0 deletions web/landing/templates/blog/post.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{% extends 'base.html.twig' %}

{%- block title -%}
Article - {{ post.title }}
{%- endblock -%}

{%- block description -%}
{{ post.description }}
{%- endblock -%}

{% block main %}
{{ block('article') }}
{% endblock %}
6 changes: 3 additions & 3 deletions web/landing/templates/blog/posts.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@
<img src="{{ asset('images/icons/pencil.svg') }}" width="32" height="32" alt="feature" class="inline mr-2 bg-blue-100 p-1 -mt-4 rounded">
<a
class="text-white"
href="{{ path('blog_post', {date: post.date, slug: post.slug}) }}"
href="{{ path('blog_post', {date: post.date | date('Y-m-d'), slug: post.slug}) }}"
>
<h2 class="inline text-4xl font-bold">{{ post.title }}</h2>
</a>
<hr class="text-blue-100 my-4 border-t-2 rounded">
<h3 class="mb-2">Posted on {{ post.date }}</h3>
<h3 class="mb-2">Posted on {{ post.date | date }}</h3>
<p class="mb-2">
{{ post.description }}
</p>
<a
href="{{ path('blog_post', {date: post.date, slug: post.slug}) }}"
href="{{ path('blog_post', {date: post.date | date('Y-m-d'), slug: post.slug}) }}"
class="text-blue-500 hover:underline mt-2"
>
Read more
Expand Down
Loading

0 comments on commit 3faf80c

Please sign in to comment.