Are You A Hack Developer?

I made a short comment while I was semi-drunk last night on a post in reddit’s r/personalfinance about my wake up call as a shitty developer.  I started getting a lot of “hits close to home” comments and private messages.  Surprised me, I thought it was just going to get buried.

I guess there’s a lot of us out there.  Those of us that taught ourselves to code.  Those of us that made/make a living developing by themselves.  I figured I should share my story.

I’ve freelanced since I was 18.  I went to undergrad for interactive design (no coding, all flash) and graduate school for Marketing and Management.  I suck at both.

I got a job out of grad school as the Webmaster for a large hospital.  After that I got $180k funding for a start up idea I had and I tried to build it by myself over the course of a year and a half… it failed.  That’s a whole different story in itself.  Then I got a job as a Webmaster for a University.

Notice a trend here? Coding solo.  No code reviews.  No requirements or standards.

The title “Webmaster” is so antiquated and seems to relate to public or government institutions.  It also means coding alone, typically.

Getting By

I had no problem with my work or how I did it.  People needed shit built or managed and I did that.  When I delivered it, it worked.  But it also broke… all. the. time.

I’d patch shitty code with more shitty code.  The source was disgusting.  But I had no idea, I figured it was fine.  Classes? git? An IDE? Local environment? Who needs that shit, I’m building stuff just fine in Notepad++ and a couple huge files with intense amounts of logic mixed into views and db calls.  Hey, they shared a header file and sometimes a footer.  I know how to INSERT and SELECT and UPDATE… who fucking needs a JOIN statement when I can just run 10 queries and a dozen for loops and nested if statements to get the data I need.

I Was Getting Paid

The hospital gig was $58k right out of grad school and rose to $70k over three years with insane benefits.  The University job was shit pay but the workload was so ridiculously light and the benefits were phenomenal.  I had so much time to freelance.

I regularly pulled in between 70-90k throughout my 20s.  Why would I think I needed to learn how to do things better?  I could pick up new languages or frameworks with ease.  I was writing VB.NET and action script for the first five years, then oh, everyone’s using WordPress now?  It’s php? Ok, I’ll learn php.

That was easy.  I mean, coding languages are all basically the same on the web, or so I thought.  You have variables, functions, you get the request variables, you go in and out of a database and you display your shit in html with, in my case, some nasty fucking javascript and inline styles.

WordPress was super easy.  Grab a free theme and some plugins.  Then I could just edit the plugin files to do what I wanted or hack through a themes templates and css.  Updates? Who needs updates, it works as is.

Chris Wiegman

Obviously, now, this is a problem.  A big one.  I hadn’t grown as a developer in ten years.  I was building sites that were getting hacked like crazy.  I always found a way to blame it on the client or WordPress and never myself.  Clients believed me, I kept getting paid, but the nightmare situation of all going to hell was building up and I had no idea.

I decided wearing nice clothes to an office 35 minutes away every day just wasn’t for me.  I was losing my mind, honestly.  I’m extremely ADD and terrible at corporate environments.  Then I met a guy.  A WordPress guy.

My favorite pub in town is a craft beer bar called Mr. Beery’s.  I met a guy there a couple years ago and we became friends.  Found out we were both primarily working in WordPress and started talking about it a lot.  He told me how he worked from home full time.  I was like… that is what I want.  No, that’s what I need.

Later on I found out Chris built a huge plugin and sold it.  iThemes Security is his work.  My mind was blown.  Dude who built one of, if not the biggest security plugins on WordPress, possibly on the web since WP is now 27% of it.  And he was my freaking neighbor.

I had talked myself up, very confidently to Chris. He told me to apply somewhere and that there are tons of agencies out there that hire remote WordPress devs.  So I submitted an application to 10up, the biggest WordPress agency out there (I think).

I was feeling good about it.  I’m a very personable guy.  Very social, good communicator and wrote great cover letters.  I got hit up by 10up almost instantly.  They wanted an interview.  OH MY GOD IT’S COMING TRUE!

The Interview

I had a video chat with a lovely lady from 10up.  We had a  great time.  Talking about culture, my family, my background, all my amazing websites I’ve built and so on.  They hit me up asking for another interview.  At this point, I felt like I had this job in the bag.

We had a second interview.  Nailed it again.  Now came the code review.

I was supposed to submit some code samples to them.  They said send them links to git repos or just some files. I decided on files because I had no clue what git even did.

So I zipped up some stuff I’d built and sent it over.  Kept telling my wife how excited I was, job was totally mine.

First reply was “hey, do you have any more code you could send over?” I didn’t know why they’d ask that.  I sent my best stuff.  So I scraped together some more code and sent it.

Then I got the email along these lines, “hey, we don’t think your coding level is where it should be for this position.  We really like you and would love to have you at our company so please feel free to apply again when you level up.”

Motivation

I was depressed man.  That shit stung more than any break up, more than any shut down, more than anything.  I was distraught.  I felt like the biggest loser, faker on the planet.  I knew nothing.  My code was shit.  I should probably just switch careers.

But Chris wouldn’t let me stay down.  He pushed me.  He told me I could level up.  He said explicitly, “let’s level you up.” I’d never had a mentor before, he didn’t even realize he was one.

Having someone believe in you is a big deal.  I didn’t know that but now I was experiencing it.

I gathered a serious amount of motivation.  First goal: build a plugin for WordPress that can be released in the public repo.  You have to submit it for review, so your code has to be at least somewhat decent to get in.

Leveling Up

I made a people lister.  It had a custom post type for people.  You put in their name and some meta data like a position at a company.  You could sort them then use a short code to display the listing in a nicely laid out format.

I look back at that code now and it’s shit, but man, it was LIGHTYEARS better than anything I had written before and it got into the repo.  I leveled up.

Next level was using a proper IDE, I got php storm and used it and only it.  I setup a git account and started making repos for every project.  I installed vagrant and VVV as a local environment.

I forced myself out of WordPress for a couple projects and learned about system architecture, routing, autoloading and so on.  I was asked to contribute to a project with some new friends I’d made in the WordPress world so I had to learn about npm and gulp and sass.

I threw myself at any opportunity to build with others.  I truly believe that was the #1 thing that has got me to where I am.

I learned NativeScript for building mobile apps.  It’s such a small community right now that when I started blogging on things I learned while developing in it I got a ton of traffic.  I still do get loads of google traffic to NativeScript articles.  I was discovering first time solutions and got indexed early.

I started applying to speak at WordCamps and surprisingly, I was accepted to five in 2016.  That was an amazing experience.

Don’t Give Up

As I grew confident in my skills and began building a small name for myself in the WordPress community I decided to give the job hunt another try.  I was told the Modern Tribe was hiring.  I redid the resume, I had this website up by then and I had a much better code catalog.

They contacted me fast and setup an interview.  I interviewed with two different people.  A culture person, then a code person.  Both interviews were awesome and they really enjoyed me as a person.

Code review was fine, they said I was moving to the final stage and they were going to give me a small 8 hour freelance project.  I was pumped, even more than last time.  I had confidence this time that was legit and founded.

I finished the project and handed it in.  A week later I had a video call with them.

I didn’t get it.  They were upset as they really wanted me but they didn’t want to set me up for failure.  They hiring a senior level developer that really needed to be a system architect at the same time.  I just wasn’t there yet.

I wanted to give up, but again… I refocused and stayed motivated.

Still Growing

So here I am now, working from home.  Got a killer full time gig for a WordPress agency based out of Toronto.  I love my team and truly love my job.  I barely freelance anymore, just a couple long term clients that I help out a few hours a month for some extra cash.

I’m a good developer now and I can say that with earned confidence.  I still have a lot to learn and I’m leveling up regularly.  I want to be the best.  I want to write the best code.  The motivation has gone no where.

Are You A Hack?

I wrote this to hopefully motivate some others out there that were the same as me.  I’m 33 now and try not to think about it, but I probably could’ve been doing this 7 or 8 years ago if I’d started the process.  But I’m happy where I am and you can be too.

P.S. If you want a code review, hit me up.  Ready to pay it forward!

Yoast Primary Category Endpoint for the WP REST API

I had a special case today where I needed to pull in posts specifically from a Yoast SEO Plugin‘s primary category.  Yoast SEO allows you to set a single, primary category for a post in WordPress.  This is an awesome feature and very useful.

A site I’m building right now uses the API to pull in the latest articles of a category in a big drop down hero navigation system.  The thing is, just pulling from a category gets a lot of the same articles when clicking around the different category options.  We wanted to pull by primary category so each click gives a unique set of posts that are very relevant to the category option.

The Struggle

There may be a super simple way to do this already but I was seriously struggling googling for the answer.  I’ve done some extending of the WP REST API but I’m still a novice so I was hoping to avoid it.  But glad I didn’t because I learned a lot and I made a cool thing!

I couldn’t find a function in Yoast that pulled post IDs or anything based on a primary category.  I needed to figure out how they assigned this.  I dug through the database and found a post meta with the key ‘_yoast_wpseo_primary_category.’  This is it, this is what I’ll use to build my end point.

The Code

First we need to register our endpoint/route.  I prefer building things in classes so I created a class:

<?php
class Rest_Api_Posts_By_Primary_Category {}

I register the endpoint in the __construct() as so:

SITE_PREFIX is something I set in my theme’s functions.php file.  You need a namespace here so make it unique based on your plugin or theme or site in general.

The callback function is where the magic happens.  In get_posts_by_primary_cat( $data ) we do a simple WP_Query that makes use of the meta_query ability.  The thing is, I need the children of categories too.  Here’s an example similar to what I’m dealing with.

Let’s say we have three categories and these categories are what we see in our navigation menu: Math, Reading, History

Then those categories each have two children: ###-Lessons, ###-Research

So our final category structure looks like

Math
 – Math-Lessons
 – Math-Research
Reading
 – Reading-Lessons
 – Reading-Research
History
 – History-Lessons
 – History-Research

If someone clicks Reading I want to load all posts that have a primary category of Reading, Reading-Lessons or Reading-Research… so I need the children.

In the function below you can see I run get_categories on the selected category withe parent argument assigned.  This gets me all the children.  I just need their ids and I need them in string format so I run a quick foreach loop.   I make sure to add the original parent id back to the new array too.  Then I run the WP_Query.

At this point you could just return $posts->posts but I needed the featured image and only a few of the pieces like title, time and a link.  So I built out what I need and return that.

Conclusion

Now to use this we simply visit http://yoursite.com/wp-json/SITE_PREFIX/v1/yoastprimary/##-catid-## and replace ##-catid-## with the actual category number.  I could’ve just made this a static class now that I think about it but whatever, you must remember to initiate it to work.  So in your functions.php of the theme or somewhere in your plugin call $rest_api_primary_cat = new Rest_Api_Posts_By_Primary_Category();

This was easy to parse in my javascript and is running great.  Hope it helps someone! Here’s the full code:

WooCommerce Buy One Get One Half Off (50% Off) Hook/Plugin – IN PROGRESS

We have a deal coming up for all of November at my work.  Buy one, get one half off.  There’s no way to do this in vanilla WooCommerce.  I looked at Dynamic Pricing and it didn’t seem to offer this ability and if it did it was crazy complicated.  I looked at some other plugins out there and found one that may work but it was pro version only and I didn’t want to pay to find out.

I figured this is pretty straight forward need so why not write up a function real fast.  Here’s my train of thought followed by a code example.  This is only a proof of concept and I still need to add – price limits (items must be over a certain price for this to work), category limits and the ability to apply this more than once to an order.  But as of now it will take the second highest priced item and give it a 50% discount.  If you have two of the same item as the highest price it will discount the amount to make it the same as taking 50% off just one of the items.

First we need to hook into woocommerce_before_calculate_totals.  This way we can change the price on the cart and on the checkout.

add_action( 'woocommerce_before_calculate_totals', 'add_custom_price' );
function add_custom_price( $cart_object ) {

Then I set variables for highest price, quantity of that item, a counter so we know if the shopper has more than 1 item in our discount range (for future use with pricing bottoms) and next highest price item.

$highest_price_id = 0;
$highest_price_quantity = 0;
$cnt = 0;
$highest_price = 0;
$next_highest_price_id = 0;
$next_highest_price = 0;

I need to optimize this, there should be no need for looping the cart twice but in a hurry to prove the concept works this morning and get something ready for our promo I did it this way.  I loop through the cart and gather all my data: highest priced item, quantity and so on.  Then we loop the contents again and reduce price where needed.

foreach ( $cart_object->cart_contents as $key => $value ) {
   if( $value['data']->price > $highest_price ) {
      $highest_price = $value['data']->price;
      $highest_price_id = $value['product_id'];
      $highest_price_quantity = $value['quantity'];
      $cnt++;
   }

   if( $value['data']->price < $highest_price && $value['data']->price > $next_highest_price ) {
      $next_highest_price = $value['data']->price;
      $next_highest_price_id = $value['product_id'];
      $cnt++;
   }
}

The final loop we first check if:

  1. Highest priced item is more than 1 quantity and we are on it in the loop
  2. There’s no other item that’s considered the second highest price.  If there is, we want to discount that and not one of the highest priced items.
  3. If any of that fails then we check if this is the next highest priced item and run our discount here
foreach ( $cart_object->cart_contents as $key => $value ) {
   if ( $highest_price_quantity > 1 && $value['product_id'] === $highest_price_id && $next_highest_price === 0 ) {
      $value['data']->price = $value['data']->price - ( $value['data']->price / $value['quantity'] ) * .5;
   } elseif ( $value['product_id'] === $next_highest_price_id && $cnt > 1 ) {
      $value['data']->price = $value['data']->price - ( $value['data']->price / $value['quantity'] ) * .5;
   }
}

The discount is based on quantity.  If someone has two of the same $99 item we don’t want to make them both $48.  We want to discount just the first item but I’m not sure if that’s even doable.  We could generate a coupon or some other more complicated options but I went with the simple approach.  Let’s take the quantity, divide the price by that (so we have two $99 items, 99/2 is $48) then take 50% of that and subtract it from the price.  Each item will have 25% subtracted basically and add up to 50% total discount on 2 items.

I’ve been testing this and it seems to be working.  I JUST put this together though so needs a lot more testing to make sure it’s working correctly.

Getting Up To Speed With NativeScript 2.3, Xcode 8 and iOS 10

tns livesync ios --emulator --watch

Unsupported version Xcode 8

Oh no …

It’s That Time

The iPhone 7 is out along with iOS 10 and things have changed.  It hit me today when I was toying with my company’s app for the first time since upgrading Xcode.

So what do? Well, the first thing I needed to solve was getting my apps running in Simulator again.  I opened up Xcode and built my app in there instead of the command line tns.  I ran it on iPhone 7 Simulator and everything popped up and seemed to be working until it crashed right away on launch.

Upgrade NativeScript to “Next”

I uninstalled NS and the tns modules and reinstalled completely using the next version (2.4).

npm uninstall nativescript -g
npm uninstall tns-core-modules
npm install nativescript@next -g
npm install tns-core-modules@next

Then I removed the ios platform from my app and added it back.  Voila, things were loading up.  Thing is, I’m lying a little, I forgot to install the @next version of tns-core-modules and even though the app was opening certain things weren’t working like trying to set the src of an Image via javascript.

Properties Not Methods

So something big is happening.  Xcode is changing some big core items from using methods to initiate and instead using properties.  For example I use local-notifications plugin to send phone notifications.  I was erroring out with:

NSNotificationCenter.defaultCenter() is not a function

Apparently that is now a property so I had to adjust the module’s code in local-notifications.ios.js to

NSNotificationCenter.defaultCenter

And it works just fine now.  Or so I believe, no more errors but haven’t tested it thoroughly.

plist.info Permission Changes

Next the app crashes when I try to open the camera.  I’m getting errors saying there’s permission issues.  Turns out I need to have some new info in app/App_Resources/plist.info

<key>NSPhotoLibraryUsageDescription</key>
<string>Photo Library Access Warning</string>

More To Come

This is all so far but I’ll be sure to add more information as I encounter it.

 

Remove Item from PayPal Invoice with the REST API

I’m building a pretty crazy system right now around the PayPal Invoice REST API.  I want the owners of the site to be able to adjust all sorts of stuff on invoices whether the status is DRAFT or SENT.  If PAID, no go.  I’m going to give them the option to copy and cancel the original if that’s possible but I haven’t dove that far in yet.

But what I did need at this point was for them to allow users and admins to adjust an invoice by removing items.  So I google searched without much luck then finally looked through the API’s code to find what I needed.

PayPal Invoice Class

Inside the class for Invoice.php is a method removeItem().  Well, I tried this and kept getting a 400 error with no description of why it wouldn’t work.  I was using a foreach loop.

foreach ( $invoice->items as $item ) {
    if( blah blah ) {
        $invoice->removeItem( $item );
    }
}

This was just not working and there were no clues as to why.  I tried adding a count variable $cnt and using removeItem( $invoice->items[ $cnt ] ) but that was producing the same error.

Adjust The Quantity

So I finally settled on just changing the quantity to 0 and, low and behold, that worked just fine.  So end of day, the line item will still be there but you can set the quantity to 0 and it will charge nothing for it.  Final code was basically:

foreach ( $invoice->items as $item ) {
   if ( strpos( $item->name, 'Item ' . $id . ':' ) !== false ) {
      $item->setQuantity( 0 );
      $invoice->update( $api_context );
   }
}

WooCommerce Subscriptions Limit Total Quantity of Subscriptions or Payment Plans in Cart

We use WooCommerce Subscriptions to setup payment plans for our products.  Deposits was our first choice but it only sent “Invoices” for future payments and did not auto charge the credit card used at initial purchase.  Not ok as our products are very expensive and people tended to ignore those invoices.

We also need to limit these purchase to one per customer.  Easier said than done.  I found a WooCommerce extension that would do the trick but we already pay so much a year for extensions we need I try to avoid that for simple functionality.

Limit Subscription

This won’t work for my needs.  The option on a subscription product only limits users from having multiple subscriptions to that particular product.  We only want one subscript for ANY product.

Solution Limits

My solution works for one shopping cart session.  I’m working on preventing others which shouldn’t be too hard by just checking the database at checkout time for active subscriptions to that user.

The Hook & Function

I went with woocommerce_add_to_cart_validation after going through quite a few other hooks and filters.  The hardest thing about finding a solution is finding what all hooks and filters are available.  Takes some serious google-fu to find the right one quickly.

This filter allows you to run a function before an item is validated and sent to the cart.  We tell our add_filter that we need two of the parameters so we can get the product id as well as the validity of the admission.  This is done with the 4th parameter we set to “2.”

Detect Variations Too

If you are using variable Subscriptions you will need to plan ahead that some items in the cart may be variations.  These have a separate class.  We must first detect if the product being added is an instance of WC_Product_Subscription which is a “Simple Subscription” in WooCommerce.  Or is an instance of WC_Product_Variable_Subscription which is like it says a version of a subscription product with variations.

The odd part that caught me off guard is when we are checking items already in the cart.  We check for WC_Product_Subscription like normal but once in the cart the product is of the WC_Product_Subscription_Variation class meaning it’s just a variation of a product and not the full product variable class.

Creating Custom Permalink Rewrite For Plugin Function Output to Content

I had a very short window to get this functioning today.  I haven’t toyed with WordPress rewrites API in some time so I had to dive right in and try to figure this out.

The Problem

I needed /plugin-content/ to rewrite to a blank page I could place a form on.  I needed this to be done without having to create a page in the WordPress admin first.  There are ways to create this page automagically when you first activate the plugin. I wanted it to not be tied to a post/page in the database but to simply work.  First I needed to build out a rewrite.  Let’s do this all in the primary plugin class for now.  Let’s imagine our class is called MyPlugin.

Building the Rewrite

First we need to add an action to init, I do this in __construct()

public function __construct() {
   add_action( 'init', array( $this, 'your_website_rewrite' ) );
   add_action( 'template_redirect', array( $this, 'make_your_website_form' ) );
}

You can see that I also hook into ‘template_redirect’ which we will address momentarily.  Here is the your_website_rewrite function:

public function your_website_rewrite() {
   add_rewrite_rule( '^your-website$', 'index.php?your-website=display-form', 'top' );
   add_rewrite_tag('%your-website%', '([^&]+)');

   if ( get_option( 'websites-cpt-flush-rewrites' ) ) {
      flush_rewrite_rules();
      delete_option( 'websites-cpt-flush-rewrites' );
   }
}

The first line creates our write which is ‘your-website’ so when we visit mysite.com/your-website the rewrite will be called.  The second parameter sends us to the site’s homepage index.php and tacks on a query string.  We need to let WordPress know to expect this query variable ‘your-website’ so we use the add_rewrite_tag function.

The way I handle flush_rewrite_rules is inside the activation of the plugin.  I set an option to true that means the rewrites do need to be flushed.  You don’t want to flush these every time the plugin is called as it can be very heavy processing.  So we only do it once after setting the rewrite rules.  They must be flushed this one time though or it won’t work.

Displaying Your Content

I originally set this up to display the content via a shortcode.  This was not the requirement though but since I had the shortcode setup and working I just used it here to display the form I needed.  That said, you can echo whatever you want in this place.  Here’s a quick look at what happens next.  We hook into the ‘template_redirect’ action with our function make_your_website_form():

public function make_your_website_form( $template ) {
   if ( get_query_var( 'your-website' ) == 'display-form' ) {
      get_header();
      echo do_shortcode(  '[WSCPT]' );
      get_footer();
      exit();
   } else {
      return $template;
   }
}

This checks the query string to see if your-website is set.  If our rewrite worked correctly then it should be there when visiting site.com/your-website.

Now inside that check we call get_header() followed by whatever we want to display then wrap it up with get_footer.  It’s important to put the exit(); here though as that is what stops all other content from being loaded.

 

Animate Image Or View Circular Motion In NativeScript

quick-demo.mov video file

I haven’t taken calculus in years and I haven’t needed it since college.  But today I did.  I needed to animate an object going in a circular motion over a graphic of a face in an iPhone/iOS app I’m developing.  These examples are purely wire framed with no official graphics or design.

What You Need

  • An AbsoluteLayout view
  • An Image view (or whatever you’d like really) inside that AbsoluteLayout
  • A starting x and y coordinate which will be the center of your circular path
  • Radius of the circle you want for your path
  • Angle (or animation speed)

Layout

 

We are going to build our layout dynamically.  I found this to be the best method for sizing things and positioning our elements.  Let’s take a look at that code.

First we need some xml to hold our generated layout items.  A simple stack layout works here, I use the horizonalAlignment and verticalAlignment to fill up the screen.  Well, it’s supposed to but doesn’t seem to function just right depending on the xml around it.  Still, it will work well enough for our demo here.

<StackLayout id="main-layout" orientation="vertical"
      horizotnalAlignment="stretch" veritcalAlignment="stretch">
</StackLayout>

Let’s fill that with some elements we want for our circular animation.  I’ve loaded this example code up with comments to explain what’s happening but I’ll point some important bits after this code block.

So our angle variable in combination with our duration speed is what controls the speed of our animation.  Each “frame” is 1000 milliseconds which is set at the very end of the setInterval function’s code block, the second parameter.

Our call to .animate() has duration: 1000 ms as well so the time it will take to transition to the next point on the circle is also 1 second.  If you think about this that means it’s going to move in a straight line from one point on the circle to the next as in this graph below.  Within 1 second, before the next frame’s location on the circle path is calculated, it animates the transition between points.

Imagine the little red circles are the calculated points transitioned to every 1 second of setInterval().  Our object moves in a straight line between them over the course of that one second.

circle-animation-lines

Starting Coordinates

The oddest problem I encountered was that my animated object shot to the outer radius of the circle from the center of it before starting reach the initial calculated frame.  What was happening is that the object is animated to it’s next frame based on it’s original x and y position.  So each calculation is based on that.  Since I start at a 0 degree angle the y axis doesn’t change when it starts but the x axis does.

I tried changing the xOrigin property to 50 (the radius) less than where I plotted it in hopes this would allow all future transition calculations to be based on that and it would seamlessly animate from the beginning but that didn’t seem to work.  So you can see in the code my solution is to subtract 50 from the x when calculated and it gives a calculation like the xOrigin is 50 less.  This seems to work just fine.

Adding Controls

In my project I have a start and stop button.  It also has a timer countdown which is not complete yet so the code isn’t going to do anything when the timer runs out.  You can see it in the main video above. I’ll post that full code below so maybe you can use some of the functionality.  It’s not commented as cleanly but notice in the xml that there are start and stop buttons with “tap” parameter which calls the respective functions in our .js file.

And the javascript

 

Use NativeScript Plugin nativescript-background-http To Send And Store Camera Pictures On PHP Server

I searched and searched and asked on slack and asked on the NS FaceBook group and everything I could think of to figure this out.  I finally pieced it together and it’s working.  So do you want to let your app users take a picture with their camera, or use one in their library for something and you need that photo stored on your web server? We let users take before/progress/after pics from using our device.  We want to store these photos so we can see results ourselves and request use from our users for advertisements.  So here’s how you do it.

nativescript-background-http

You need to make sure and import your camera ui and also this plugin.  It’s extremely awesome and works great.  You can get it by running

tns plugin add nativescript-background-http

EDIT: For some reason when I put this on an actual device it wouldn’t save the photos.  When on the actual phone it has a problem with using knownFolders.currentApp() and a custom folder, so I change that line from

fs.knownFolders.currentApp().path + /saved_images;

to

fs.knownFolders.documents().path;

and it worked just fine.

After setting that up use the below code, or whatever parts of it you’d like, to make the NS function and push the upload to your server.  A couple notes though, I use a folder called /saved_images in my /app project directory to store the files before sending.  I’m not sure this is necessary but I wanted to resize to a maximum of 800px wide or height while retaining proportion.  It is extremely important this directory is created if you use this filepath or your script will fail and you won’t know why because error logging here doesn’t do anything.

Also, I store a global configuration variable for my api’s URL, so I use url: config.apiUrl in my request options.

Saving The Image In PHP

So the config.apiUrl points directly to my php file (ex:server.com/apifile.php).  In this file you need to access file_get_contents(‘php://input’) to access the streamed data coming in.  This is how you work with forms submitted using content type “application/octet-stream” to get the file data.  With this data you can simply save it however you’d like using file_put_contents.  There’s other security concerns you will need to address that I’m not going over here as they are different all different applications of this process.  But here’s a quick, simple line for saving the image to a /uploads/ directory:

$all_headers = apache_request_headers();
$newimg = file_put_contents('uploads/' . $all_headers['File-Name'], file_get_contents('php://input'));

Now your image has been saved!

Additional User Data Needed

If you are storing this image and attaching it to a user or any other kind of data you can pass these as header fields just as you did the File-Name.  In your JS just under the line:

"File-Name": filename

Add a comma and put the next field you might need such as:

"File-Name": filename,
"Email-Add": email

Enjoy!

Touch “Hold” Function: Button Held Down In NativeScript

Tonight I needed to run a function constantly while a button is being held down in my app.  I found the gestures functionality and it had what I needed but I had to do some work to get it to perform what I was after.

My task was this, when someone puts their finger down on a ‘Record’ button I need to store what the sound level was every 10/1000 of a second.  So here’s what I did.

Using Gestures Touch to Define “Hold”

When the page is loaded I assign the button element to a variable then I add the on touch function.  It’s important to declare that button’s variable at the beginning of your JS so it’s available in all functions.  Also important to require your view module and gesture.  Here’s a snippet that covers all of that:

var viewModule = require("ui/core/view");
var audio = require("nativescript-audio");
var timer = require("timer");
var gestures = require("ui/gestures");
var documents = fs.knownFolders.currentApp();
var recorder = new audio.TNSRecorder();
var isRec = false;
var timeRec;
var currentRecording = new Array();
var page;
var soundlevel;

exports.loaded = function(args) {
    page = args.object;
    soundlevel = viewModule.getViewById(page, "soundlevel");

    soundlevel.on(gestures.GestureTypes.touch, function (args) {
        if(args.action == "down" || args.action == "up") {
            recordVolume( args.action );
        }
    });
}

Now that I’m calling a function, let’s tell that function what to do.  We have our “soundlevel” view which is just a button with id=”soundlevel” and we’ve assigned an action of “on” for it when gesture touch occurs.  The gesture touch passes args that include “action” as a property.  That property can be “down”, “up” amongst other things, but these are what we need.  So now let’s build a function to handle the hold.

function recordVolume(action) {
    var recorderOptions = {
        filename: documents.path + "/recording.caf",
        infoCallback: function() {
            console.log();
        },

        errorCallback: function() {
            console.log();
        }
    };
    if( action == "up" ) {
        recorder.stop();
        isRec = false;
        timer.clearInterval(timeRec);
    } else {
        recorder.start( recorderOptions );
        currentRecording = new Array();
        isRec = true;
        timeRec = timer.setInterval( function() {
            var barWidth = Math.round((160+Number(recorder.getMeters(0, "average")))/160*100);
            currentRecording.push(barWidth);
        }, 10);
    }
}

Note: barWidth is an integer I end up assigning as a percentage of the screen width.  This way I can give a visualization of sound level.

Here we check wether the action is up or down and do our desired functionality based on that.  If it’s “up” that means the finger has been lifted from the screen so we stop everything.

If the action is “down” that means the user has just pressed the button.  So we user the timer library and set an interval.  Basically every 10/1000 of a second we perform a calculation of the sound level and push that to our array of sound levels.  Now we can analyze that and do what we want to do!