GitHub
Tests: 12 • Commercial: 2 • Pet projects: 4 • Legacy: 4
Total: 22

.NET Framework

Test
2021

Project Request

ASP.NET MVC • C# • SQL Server
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2020

ProjectC

ASP.NET MVC • C# • JSON • jQuery
JSON data processing.
Test
2020

Vehicle Maintenance

ASP.NET MVC • VB.NET • JSON
Idea of the project: if someone wants to order a project development, here you can send an application.
Test
2019

Movie Navigator

ASP.NET MVC • VB.NET
Request information about movie from IMDB.
Test
2018

Customers Exchange

ASP.NET MVC • C# • SQL Server
Automated teller machine emulation.
Test
2016

ATM

ASP.NET MVC • C#
Automated teller machine emulation.

.NET Core

Pet project
2022

Mail Daemon

.NET 9 • Console • JSON
Utility to send mails with customizable settings.

Custom

Code
2024

Buns of code

.NET Framework • C# • JavaScript
Code snippets from my projects, ready to use; tiny tests; code examples.

PHP

Test
2024

Mediabox

PHP 8 • Laravel 11 • Vue.js • Composer • SQLite
Test project for media files management.
Test
2020

Loan Castle

PHP • MariaDB
Jums jāizstrādā kāda lielāk projekta prototips. Izstrādājot prototipu, paturiet prātā, ka projektam attīstoties, šo prototipu varētu vajadzēt pilnveidot.
Test
2020

Content Management

PHP • MySQL • AJAX
Создать простой сайт, где будет страница с формой для авторизации и страница для авторизованного пользователя.
Test
2019

Laravel

PHP • Laravel • Vue.js • Composer • SQLite
Izveidot aplikāciju, kura ik pēc noteikta intervāla (60 sekundes) veic ierakstu datubāzē izmantojot Laravel freimworka iebūvēto funkcionalitāti.
Test
2019

Phone Check

PHP • JavaScript • JSON • Docker
Implement application to detect country by phone number.

Frontend

Test
2021

Forex Wall

npm • React
For this exercise, what we need is a simple live wall for tracking currencies.

Business projects

Commercial
2008

Certification Center

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Dapper • JavaScript • jQuery • Git
Transport registration and certification services in Latvia, Customer Relationship Management.
Commercial
2000

Amerikas Auto

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • SQL Server • ADO.NET • Entity Framework • JavaScript • jQuery • Git
Car service and spare parts for all USA and European car models, Customer Relationship Management.

Pet projects

Pet project
2023

Geolocation Assistant

.NET 8 • ASP.NET Core • C# • Web API • JSON • Git
Website for determining geolocation by IP or geotagged photo.
Pet project
2008

Web Dynamics

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
Software development blog. Articles, books, videos, content management.
Pet project
2000

Blackball

.NET Framework 4.8 • ASP.NET Web Forms • C# • LINQ • Web API • JSON • XML • SQL Server • Dapper • JavaScript • jQuery • SVG • Git
My entertainment portal created from scratch.

Good old times

Legacy
2000

DOS Clock

Turbo Pascal • Assembler
Digital clock.
Legacy
2000

BrainOut

Turbo Pascal • Assembler
Tank battle game.
Legacy
1999

Airport Administrator

Turbo Pascal
Курсовая работа в институте.
Legacy
1998

Atomizer

Turbo Pascal • Assembler
Atomizer, aka «Studio2D». Graphic raster editor. AGI is my own «Atomizer Generated Image» file format.

Laravel

2019 Test

Izveidot aplikāciju, kura ik pēc noteikta intervāla (60 sekundes) veic ierakstu datubāzē izmantojot Laravel freimworka iebūvēto funkcionalitāti.

PHP Laravel Vue.js Composer SQLite
Information
Source code
  app
  Http
  Auth
  css
  js
  js
  lang
  en
  sass
  app
  data
  logs
  Unit
  src
  src
  lib
  docs
  en
  src
  docs
  en
  lib
  src
  Cron
  Cron
  src
  filp
  src
  css
  js
  Util
  src
  ORM
  Spot
  test
  Core
  Text
  Type
  Xml
  Core
  Text
  Type
  Xml
  html
  src
  src
  src
  Auth
  make
  auth
  Bus
  Auth
  Bus
  Http
  Mail
  View
  Auth
  Bus
  Http
  Http
  Json
  Log
  Mail
  html
  text
  Jobs
  View
  src
  src
  Util
  docs
  Pass
  Pass
  Pass
  doc
  src
  Curl
  doc
  f001
  f002
  f003
  f004
  f005
  f006
  f007
  f008
  src
  Date
  Spl
  src
  Lang
  List
  doc
  lib
  Node
  Expr
  Cast
  Name
  Stmt
  test
  code
  expr
  uvs
  stmt
  loop
  expr
  stmt
  Node
  Stmt
  src
  opis
  src
  dist
  lib
  src
  xml
  xml
  src
  Unit
  src
  src
  Tags
  src
  src
  src
  Call
  Node
  Call
  Util
  src
  Node
  Html
  css
  js
  Xml
  HTML
  XML
  src
  src
  src
  src
  src
  Stub
  Hook
  Util
  Log
  PHP
  cli
  1149
  1216
  1265
  1330
  1335
  1337
  1348
  1351
  1374
  1437
  1468
  1471
  1472
  1570
  2085
  2137
  2145
  2158
  2366
  2380
  2382
  2435
  244
  2448
  2724
  2725
  2731
  2811
  2830
  2972
  3093
  3107
  3156
  322
  3364
  3379
  3380
  3396
  433
  445
  498
  503
  581
  74
  765
  797
  873
  Trac
  1021
  523
  578
  684
  783
  fail
  unit
  Util
  PHP
  psr
  src
  log
  Psr
  Log
  Test
  src
  psy
  src
  Sudo
  Util
  test
  Sudo
  Util
  box
  uuid
  src
  Time
  Node
  Time
  src
  src
  diff
  src
  out
  src
  src
  src
  src
  src
  src
  src
  src
  doc
  lib
  Mime
  Pop
  Auth
  Mime
  bug
  unit
  Mime
  Auth
  dkim
  Node
  Node
  psr4
  phpt
  .dot
  b
  a
  A
  B
  C
  copy
  A
  B
  C
  one
  b
  .dot
  a
  dir
  File
  Test
  File
  test
  Test
  Log
  Log
  mime
  Part
  test
  Part
  glob
  Test
  data
  dat
  res
  Util
  Util
  Test
  css
  js
  Test
  Test
  src
  src
  Css
  Rule
  src
  src
  .env
  null
Root / vendor / swiftmailer / swiftmailer / doc / plugins.rst
Plugins ======= Plugins exist to extend, or modify the behaviour of Swift Mailer. They respond to Events that are fired within the Transports during sending. There are a number of Plugins provided as part of the base Swift Mailer package and they all follow a common interface to respond to Events fired within the library. Interfaces are provided to "listen" to each type of Event fired and to act as desired when a listened-to Event occurs. Although several plugins are provided with Swift Mailer out-of-the-box, the Events system has been specifically designed to make it easy for experienced object-oriented developers to write their own plugins in order to achieve goals that may not be possible with the base library. AntiFlood Plugin ---------------- Many SMTP servers have limits on the number of messages that may be sent during any single SMTP connection. The AntiFlood plugin provides a way to stay within this limit while still managing a large number of emails. A typical limit for a single connection is 100 emails. If the server you connect to imposes such a limit, it expects you to disconnect after that number of emails has been sent. You could manage this manually within a loop, but the AntiFlood plugin provides the necessary wrapper code so that you don't need to worry about this logic. Regardless of limits imposed by the server, it's usually a good idea to be conservative with the resources of the SMTP server. Sending will become sluggish if the server is being over-used so using the AntiFlood plugin will not be a bad idea even if no limits exist. The AntiFlood plugin's logic is basically to disconnect and the immediately re-connect with the SMTP server every X number of emails sent, where X is a number you specify to the plugin. You can also specify a time period in seconds that Swift Mailer should pause for between the disconnect/re-connect process. It's a good idea to pause for a short time (say 30 seconds every 100 emails) simply to give the SMTP server a chance to process its queue and recover some resources. Using the AntiFlood Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~ The AntiFlood Plugin -- like all plugins -- is added with the Mailer class's ``registerPlugin()`` method. It takes two constructor parameters: the number of emails to pause after, and optionally the number of seconds to pause for. When Swift Mailer sends messages it will count the number of messages that have been sent since the last re-connect. Once the number hits your specified threshold it will disconnect and re-connect, optionally pausing for a specified amount of time:: // Create the Mailer using any Transport $mailer = new Swift_Mailer( new Swift_SmtpTransport('smtp.example.org', 25) ); // Use AntiFlood to re-connect after 100 emails $mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100)); // And specify a time in seconds to pause for (30 secs) $mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(100, 30)); // Continue sending as normal for ($lotsOfRecipients as $recipient) { ... $mailer->send( ... ); } Throttler Plugin ---------------- If your SMTP server has restrictions in place to limit the rate at which you send emails, then your code will need to be aware of this rate-limiting. The Throttler plugin makes Swift Mailer run at a rate-limited speed. Many shared hosts don't open their SMTP servers as a free-for-all. Usually they have policies in place (probably to discourage spammers) that only allow you to send a fixed number of emails per-hour/day. The Throttler plugin supports two modes of rate-limiting and with each, you will need to do that math to figure out the values you want. The plugin can limit based on the number of emails per minute, or the number of bytes-transferred per-minute. Using the Throttler Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~ The Throttler Plugin -- like all plugins -- is added with the Mailer class' ``registerPlugin()`` method. It has two required constructor parameters that tell it how to do its rate-limiting. When Swift Mailer sends messages it will keep track of the rate at which sending messages is occurring. If it realises that sending is happening too fast, it will cause your program to ``sleep()`` for enough time to average out the rate:: // Create the Mailer using any Transport $mailer = new Swift_Mailer( new Swift_SmtpTransport('smtp.example.org', 25) ); // Rate limit to 100 emails per-minute $mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin( 100, Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE )); // Rate limit to 10MB per-minute $mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin( 1024 * 1024 * 10, Swift_Plugins_ThrottlerPlugin::BYTES_PER_MINUTE )); // Continue sending as normal for ($lotsOfRecipients as $recipient) { ... $mailer->send( ... ); } Logger Plugin ------------- The Logger plugins helps with debugging during the process of sending. It can help to identify why an SMTP server is rejecting addresses, or any other hard-to-find problems that may arise. The Logger plugin comes in two parts. There's the plugin itself, along with one of a number of possible Loggers that you may choose to use. For example, the logger may output messages directly in realtime, or it may capture messages in an array. One other notable feature is the way in which the Logger plugin changes Exception messages. If Exceptions are being thrown but the error message does not provide conclusive information as to the source of the problem (such as an ambiguous SMTP error) the Logger plugin includes the entire SMTP transcript in the error message so that debugging becomes a simpler task. There are a few available Loggers included with Swift Mailer, but writing your own implementation is incredibly simple and is achieved by creating a short class that implements the ``Swift_Plugins_Logger`` interface. * ``Swift_Plugins_Loggers_ArrayLogger``: Keeps a collection of log messages inside an array. The array content can be cleared or dumped out to the screen. * ``Swift_Plugins_Loggers_EchoLogger``: Prints output to the screen in realtime. Handy for very rudimentary debug output. Using the Logger Plugin ~~~~~~~~~~~~~~~~~~~~~~~ The Logger Plugin -- like all plugins -- is added with the Mailer class' ``registerPlugin()`` method. It accepts an instance of ``Swift_Plugins_Logger`` in its constructor. When Swift Mailer sends messages it will keep a log of all the interactions with the underlying Transport being used. Depending upon the Logger that has been used the behaviour will differ, but all implementations offer a way to get the contents of the log:: // Create the Mailer using any Transport $mailer = new Swift_Mailer( new Swift_SmtpTransport('smtp.example.org', 25) ); // To use the ArrayLogger $logger = new Swift_Plugins_Loggers_ArrayLogger(); $mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($logger)); // Or to use the Echo Logger $logger = new Swift_Plugins_Loggers_EchoLogger(); $mailer->registerPlugin(new Swift_Plugins_LoggerPlugin($logger)); // Continue sending as normal for ($lotsOfRecipients as $recipient) { ... $mailer->send( ... ); } // Dump the log contents // NOTE: The EchoLogger dumps in realtime so dump() does nothing for it echo $logger->dump(); Decorator Plugin ---------------- Often there's a need to send the same message to multiple recipients, but with tiny variations such as the recipient's name being used inside the message body. The Decorator plugin aims to provide a solution for allowing these small differences. The decorator plugin works by intercepting the sending process of Swift Mailer, reading the email address in the To: field and then looking up a set of replacements for a template. While the use of this plugin is simple, it is probably the most commonly misunderstood plugin due to the way in which it works. The typical mistake users make is to try registering the plugin multiple times (once for each recipient) -- inside a loop for example. This is incorrect. The Decorator plugin should be registered just once, but containing the list of all recipients prior to sending. It will use this list of recipients to find the required replacements during sending. Using the Decorator Plugin ~~~~~~~~~~~~~~~~~~~~~~~~~~ To use the Decorator plugin, simply create an associative array of replacements based on email addresses and then use the mailer's ``registerPlugin()`` method to add the plugin. First create an associative array of replacements based on the email addresses you'll be sending the message to. .. note:: The replacements array becomes a 2-dimensional array whose keys are the email addresses and whose values are an associative array of replacements for that email address. The curly braces used in this example can be any type of syntax you choose, provided they match the placeholders in your email template:: $replacements = []; foreach ($users as $user) { $replacements[$user['email']] = [ '{username}'=>$user['username'], '{resetcode}'=>$user['resetcode'] ]; } Now create an instance of the Decorator plugin using this array of replacements and then register it with the Mailer. Do this only once! :: $decorator = new Swift_Plugins_DecoratorPlugin($replacements); $mailer->registerPlugin($decorator); When you create your message, replace elements in the body (and/or the subject line) with your placeholders:: $message = (new Swift_Message()) ->setSubject('Important notice for {username}') ->setBody( "Hello {username}, you requested to reset your password.\n" . "Please visit https://example.com/pwreset and use the reset code {resetcode} to set a new password." ) ; foreach ($users as $user) { $message->addTo($user['email']); } When you send this message to each of your recipients listed in your ``$replacements`` array they will receive a message customized for just themselves. For example, the message used above when received may appear like this to one user: .. code-block:: text Subject: Important notice for smilingsunshine2009 Hello smilingsunshine2009, you requested to reset your password. Please visit https://example.com/pwreset and use the reset code 183457 to set a new password. While another use may receive the message as: .. code-block:: text Subject: Important notice for billy-bo-bob Hello billy-bo-bob, you requested to reset your password. Please visit https://example.com/pwreset and use the reset code 539127 to set a new password. While the decorator plugin provides a means to solve this problem, there are various ways you could tackle this problem without the need for a plugin. We're trying to come up with a better way ourselves and while we have several (obvious) ideas we don't quite have the perfect solution to go ahead and implement it. Watch this space. Providing Your Own Replacements Lookup for the Decorator ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Filling an array with replacements may not be the best solution for providing replacement information to the decorator. If you have a more elegant algorithm that performs replacement lookups on-the-fly you may provide your own implementation. Providing your own replacements lookup implementation for the Decorator is simply a matter of passing an instance of ``Swift_Plugins_Decorator_Replacements`` to the decorator plugin's constructor, rather than passing in an array. The Replacements interface is very simple to implement since it has just one method: ``getReplacementsFor($address)``. Imagine you want to look up replacements from a database on-the-fly, you might provide an implementation that does this. You need to create a small class:: class DbReplacements implements Swift_Plugins_Decorator_Replacements { public function getReplacementsFor($address) { global $db; // Your PDO instance with a connection to your database $query = $db->prepare( "SELECT * FROM `users` WHERE `email` = ?" ); $query->execute([$address]); if ($row = $query->fetch(PDO::FETCH_ASSOC)) { return [ '{username}'=>$row['username'], '{resetcode}'=>$row['resetcode'] ]; } } } Now all you need to do is pass an instance of your class into the Decorator plugin's constructor instead of passing an array:: $decorator = new Swift_Plugins_DecoratorPlugin(new DbReplacements()); $mailer->registerPlugin($decorator); For each message sent, the plugin will call your class' ``getReplacementsFor()`` method to find the array of replacements it needs. .. note:: If your lookup algorithm is case sensitive, you should transform the ``$address`` argument as appropriate -- for example by passing it through ``strtolower()``.