Categories
Slim 4 Framework

PHP Slim 4 Redirect to Named Route, also Using Slim-Flash

This took a long time to figure out. I was using the official Slim-Skeleton, and it’s not really set up to handle this use case.

I was making a traditional HTML app (minimal JS). After an upload, I wanted to send the user back to the file list, named ‘list’, and flash a success message.

After installing the Slim-Flash package, it didn’t work. This package needed the session to be enabled. I messed with the Session middleware to always enable sessions.

Then, I needed to implement redirection. I didn’t want to concatenate a URL in the action, because that’s what named routes are for.

To use a named route, you need to use the RouteParser’s urlFor() method.

To get the RouteParser, you use

$app->getRouteCollector()->getRouteParser()

But, how do you get the App? In proper Hollywood style inversion of control frameworks, you should not touch the App. Such is the case with slim-skeleton.

A different skeleton called slim4-skeleton has the solution: put the App into the DI Container, and create the app using the container. Then, you can always get a reference to the App from the DI container.

$this->container->get( App::class );

So, the Action has a reference to the container, and the container holds a reference to the App. I guess that’s a circular reference. Oh well. This kind of thing is required for traditional form-based HTML apps. Redirect is the best way.

Showing the flash message is a little complicated, because the package doesn’t explain how.

You get an array of messages, which should be passed to the template. You then loop over these.

The structure is

[
      'namedkey' => [ 0 => 'message 0', 1=>'message 1'],        
      'namedkey2' => [ 0 => 'message 0 of namedkey2' ]  
]

The named keys are used to classify the messages. I would use “success”, “warning”, and “error”.

The code to print the messages:

    {% for key,list in messages %}
        {% for item in list %}
            <div class="box flash {{ key }}">{{ item }}</div>
        {% endfor %}
    {% endfor %}
Categories
Uncategorized

Consumer Demand Aggregation

Reading up on this. I thought I’d set up BuddyPress for something like this, and it’s not working out due to weird redirect problems. Ditching platform 😦

https://medium.com/adventures-in-consumer-technology/how-aggregation-theory-is-fueling-a-multi-trillion-dollar-technology-revolution-ce5ab03ca4bc

https://stratechery.com/2015/aggregation-theory

https://stratechery.com/2017/defining-aggregators/

https://stratechery.com/2015/netflix-and-the-conservation-of-attractive-profits/

This one is hype, but an interesting situation. Blockchain tokens to sell Australian beef in China. https://beefledger.io/the-perfect-storm-consumer-aggregation/

Looking at alternatives to BuddyPress.

https://wbcomdesigns.com/buddypress-alternatives-for-a-wordpress-website/

BuddyBoss – not a BuddyPress add on – it’s a “theme” that includes social network software, with online learning features. Premium theme.

PeepSo – framework to create a social network, with paid add ons like forums and groups. It’s “free” but the Gecko theme is $99, and you can’t really use a different theme.

PeepSo

I’m kind of new to this kind of WP plugin. It basically turns WordPress into Facebook, or Diaspora, Twitter, FF, etc.

PeepSo doesn’t use WP’s posts and pages. It uses custom post types, so PeepSo posts are separate from WP Posts. Pages are used as integration points to pull in PeepSo content.

PeepSo uses WP’s users.

The layout is created with widgets and specific PeepSo widgets. Making a stripped down theme shouldn’t be too hard.

The code is a little weird. The autoloader… has a weird naming convention. The PHP codebase looks OK though. Not too weird, but also, not contemporary OOP using the regular naming conventions. Also, some very long files. Most of the code was last committed in 2015.

Despite these problems, it looks like a promising platform. The old checkins are encouraging, becauase it’s a sign that the code is decoupled from WP enough that it doesn’t need changes.

Categories
Uncategorized

Useful Links for File Upload Application

Containerized application to manage file uploads. Portable to different applications so the entire thing is reused, without needing to be linked into a larger application.

Custom file upload button hack, to make an upload button that fills an invisible file input field in a form. Didn’t end up using it.

Instead, I pulled out the Materialize code and reverted to traditional POST HTML. Fewer dependencies = longer legacy life.

Categories
Uncategorized

Self Hosted Cloud Coding

I’ve moved a lot of my development work “into the cloud”, except that this “cloud” is a computer we own.

Instead of coding in a browser, I code in a terminal window, and ssh into the server.

To create a nicer environment, I use vim, tmux, and zsh.

I’m still working out the keymappings, but it’s an acceptable coding environment. The best part is that it’s a single environment, rather than a different environment on each computer I use.

Since I use all three platforms, I did make one change to the keymappings that really helps.

On all the machines, I try to do the following key mappings:

Caps-Lock = Control on all OSs

Lower left key (control on PC) = Windows Key aka Super

Next key to the right = Alt

Key to left of spacebar = Control on PC, Command on Mac

When I’m in the terminal, I try to use caps-lock as the control key. This way, it’s the same on all three platforms.

When I’m in the windowing system, I use the key next to the spacebar to do cut, copy, paste, print, etc. typical Mac-style accelerators.

Categories
Slim 4 Framework

PHP Slim 4: Accessing Settings in the Router

I wanted to access the settings (from settings.php) within route.php. Here’s what I did.

Categories
Slim 4 Framework

Learning Slim 4 PHP

I should probably have stuck with Symfony, but I had played with Slim 3 before, and wanted to use Slim 4. My first impressions:

  • Everything seems to be easy, until you want to make a more MVC app.
  • It’s all about PSRs, which means a lot of long interface names.
  • I need to find some tutorials.

It’s taking a lot longer to learn this simple framework than it took to get started with Symfony or Laravel.

I’ll be blogging about this a bit, here. I don’t want it up on technote.fyi because, well, it’s already got a lot of low quality cruft that needs to be deleted.

Categories
Uncategorized

Decision Support Systems, Notes

Car Loan – performs the loan cost calculation, maybe evaluate cost-benefit, maybe affordability

Blending – blending similar items with different compositions to create a final product with a desired composition e.g. blending brands of lemonade and ales to make a shandy; using two different brands of spice mix to create a consistent end product flavor. http://www.ifrj.upm.edu.my/23%20(03)%202016/(44).pdf

Product Mix – marketing decision support to determine the optimal mix of products to sell, so that different products don’t compete with each other. e.g. Prius V was discontinued because it competed with Highlander hybrid. Search.

Worker Scheduling – a problem of combination or trying out different mixes of workers to satisfy labor needs for a day, but also avoid overscheduling a worker for a week, or to follow the requirements of a labor union contract. This shows how to use a spreadsheet solver feature to optimize scheduling https://support.office.com/en-us/article/Using-Solver-to-schedule-your-workforce-7AE8DD69-7582-4F41-83F1-EA3543398B46

Production Planning – organizes materials and time-and-effort in a production process to meet deadlines. Decision support tools can model different alternative scenarios, and can help with project estimates. https://www.ercim.eu/publication/Ercim_News/enw58/kis.html

Also planning out production to meet market demand.

Transportation – customer decisions about what mode of transport to use (based on time versus cost), urban planning scenario simulators, moving people, moving things, risks, costs, speed, volume. https://www.igi-global.com/book/using-decision-support-systems-transportation/126402

Stock Trading Simulation – simulate effects of different decisions, test program trading strategies on historical data.

Capital Budgeting – https://www.researchgate.net/publication/260788973_Decision_Support_Software_for_Capital_Budgeting

https://yourbusiness.azcentral.com/companies-make-capital-budgeting-decisions-11272.html

Regression Application – regression analysis for decision support. Predicting a future value based on past values. https://en.wikipedia.org/wiki/Regression_analysis

Exponential Utility – I don’t understand this function. https://en.wikipedia.org/wiki/Exponential_utility

Queueing Simulation – simulate networks of queues to get stats about how long people wait in each queue. optimize to reduce waits, and reduce downtime of non-busy queues. http://www.simjs.com/queuing/

Option-Pricing – option pricing formulas are well known. https://www.investopedia.com/articles/optioninvestor/07/options_beat_market.asp
Stock Beta – beta is volatility. The beta formula is a statistical measure of cyclical variance. https://www.investopedia.com/ask/answers/070615/what-formula-calculating-beta.asp
Portfolio Optimization
Data Envelopment Analysis –  https://en.wikipedia.org/wiki/Data_envelopment_analysis  I think I kind of understand this. It’s a linear programming method to analyze situations with multiple inputs and outputs, and compare the efficiency of different “decision making units” (DMU). A DMU might be a company, or a division, or even a configuration of inputs.

 

 

Categories
Uncategorized

Bug? Safari Array.reduce requires an initial value.

I just hit this issue.

MDN doesn’t say that reduce() requires an initial value, just that the functions behavior changes.

So, it’s off spec. I don’t know how to file a bug with Apple. This is going to take a while.

The bug itself is simple. This works in FF, Chrome, and Edge, but not Safari:

x.reduce( (a, b) => a + b );

This works in Safari and all the rest:

x.reduce( (a, b) => a + b, 0 );

 

Categories
Uncategorized

Almost ready to abandon my views and control

This SF Active port has been a real pain in the ass, largely because I’m trying to preserve the old program’s functionality.

As I’ve refactored the code, it’s gotten better, but some bigger architectural headaches are emerging. The Template class issue in the last post was a real headache. It was doubly frustrating because I figured out that the templating language had some code to enable nested templates, but the feature wasn’t used.

Categories
Uncategorized

Bit by preg_replace() Backreferences

Damn. I spent a long time tracking this one down.  I migrated the platform from php 5 to php 7, and that meant the ereg_replace() methods were gone.  So I replaced them with preg_replace() and fixed up the regexes.

The title already tells you what’s up, so, you’re going to feel really smart, and I’m going to look really stupid.  It was a lot harder than it sounds.

Generally, things went well, but there was this weirdass bug with the following characteristics:

  • Dollar amounts got wiped out.  So $100,000 would show up as 0,000.
  • But it was only the first two digits and the dollar sign.
  • I played around with it a while, but it was hard to figure out what was happening, so I needed to refactor things to trace where it was happening.

Then I went down a deep rabbit hole, fixing up the SFActive code to make it more OO, slightly MVC, and testable.  It wasn’t bad, but what a pain.  It’s still not done, but it’s been a learning experience.

What I learned is, sometimes, you need to refactor to a point, and then use the knowledge to just write a new application.  A lot of the work is comprehending the code and tearing it apart.

Anyway, I digress.  I was writing some article on the site, and got bit by the bug. It was quite upsetting, so, I started to poke around in the code, and tried some different things.  I discovered:

  • $0 gets replaced with the name of a key TPL_LOCAL_ARTICLE.
    • That’s the name of a key that corresponds to the field in the template.

I did a once over on the docs for preg_replace, but it was around 4pm, and kind of hot, so I rushed through the docs a little too fast.

I kept altering the code – the running code – and started copying functions and creating new code paths where I could add debugging info.  With each iteration of testing, it just seemed to take me closer to the templating class.

That thing had some annoying code.  It had this:

$this->$var

Yeah, instead of using an associative array, template values were stored as properties on the object.

I know it’s valid code. It’s just bad form. You get this level of indirection, and it is almost invisible in the code.   So I added an array, and coded it up like this:

$this->context[$var]

Ultimately, it’s not that different… but the thing is, if there was some weird code path I didn’t notice which added a property to the object, it wouldn’t affect this array.  The context is a namespace for values that go into the template.  It’s not the object’s namespace.

That didn’t fix it, but I could add more code to narrow down the problem zone.

I would just dump the value of variables, like this:

file_put_contents('/tmp/y', $defaults);

One goes before, and one goes after. So you can see the inputs and the output.

Those just get moved up and down the code, to probe the values.

Yeah, I should use a debugger.  I just don’t have one set up for the live server.

As I went through, I’d clean up code. Indentation was fixed. Just the usual, so visual inspection was easier.

I also discovered why template variables started with TPL_.  It’s because the original template fields were surrounded by brackets: {LOCAL_ARTICLE}.  At some point, they hit a weird bug, kind of like this:

ereg_replace("{$val}", $replace, $subject);

When PHP is interpolating a string, and sees {} around a scalar variable, it considers the { and } to be delimiters around an expression, and replaces the brackets and expression with the value in the brackets.  So “$val” and “{$val}” result in the same string!

PHP was eating up the brackets, and messing up the template behavior.

To work around it, the programmers just went with that behavior, and prefixed values with TPL_, which was an uncommon string.

Back to the story.

Eventually, it narrowed down to one function.

Then it was preg_replace.

At that point, it clicked.  It was some kind of backreference in the string.

I replaced preg_replace() with str_replace() and adjusted accordingly.

It worked.

Then I verified in the docs: strings of the form $0 and \\0 are considered backreferences to the patterns captured in the regular expression.

What was happening was that TPL_LOCAL_ARTICLE was being matched, and replaced references to $0.

The other 98 values, $1 to $99, didn’t have any values, so they got replaced with nothing.

The Antipattern

If you replace a component with a more feature-full, better component, you may induce a bug based around a new feature that didn’t exist before.

Security

I don’t know what kind of security implications this may have, but here are some possible risks.

If you use preg_replace to strip out malicious code, then adding $0 after that code could expose it.  The following example shows how, if you have an administrator who inserts a $0 into the replacement text, then any attempt to remove a script tag with preg_replace is subverted.

<?php
$userinput = "alert();";
$admininput = "foo $0 bar";
echo preg_replace("/<script>.+<\/script>/",$admininput, $userinput);

While that seems like a remote possibility, there are some possible strings where you could hide $0, like in a username: $0$0RRY $1NG$0NG

My story above corresponded to this:

<?php
$field = "{field}";
$template = "text {field} text";
$userinput = "foo $0 bar";
echo preg_replace($field, $userinput, $template);

So, in my situation, the user input was being put into the replacement string… which shouldn’t be user input, or if it is, sanitize it first, with preg_quote().

See Also

https://bitquark.co.uk/blog/2013/07/23/the_unexpected_dangers_of_preg_replace

http://php.net/manual/en/reference.pcre.pattern.modifiers.php