How to build scheduled batch-style application

Hi All.

The solution I am building has the need for a background process to regularly check the database, and based upon some flags and the time, it needs to update data in the database. A fairly common requirement.

Rather than start from scratch, and given I already have built internal libraries in SC to do the required processing for other parts of the system, I would like to build the background batch app in SC. The background batch app does not have to be executed in a critical timeframe, it just needs to check the DB every 30 mins or so. Hence I was going to use cron to kick off a PHP process regularly (it does not have to be a daemon driven off a signal or anything that elaborate).

Is there a recommended app type, or an approach I can use to do this?

I tried building a very quick blank app, but when I tried to test run it in background (command line ‘php /index.php’ it crashed out with a series of warnings (library not found) and finally an uncaught exception.

Any ideas appreciated. Regards.

A quick update, if I execute the app from the right directory, I avoid the errors mentioned above. But now the app outputs a whole bunch of HTML, as though it was talking to a browser, as you would expect. So now I am looking for some way to stop that output. I assume I can put my code in the Execute event.

Did you try with a blank app?
That app type shouldn’t output anything you don’t explicitly (e.g. using echo) and it has only the onExecute event that will be triggered when the app is run.

I am sorry, I misled you. I did create a blank app (not a control app). I will edit my prior comments.

This is the simplest app - I hardly changed anything when I used the New App wizard.

The Execute event only has three lines in it:
error_log(‘Batch application works.’,0);
sc_log_add (“testing”, “Batch application works.”);
echo ‘Done’;

When I generate and run this from within SC, I do get “Done” displaying on a blank page and an entry is made in the log table associated with the log schema. But I cannot find an entry in any error log resulting from the error_log() statement - is this expected? Should this work within an SC app (I have not tried this before)?

If I then use a terminal window and go to the directory where blank the app is, and enter ‘php index.php’, a whole bunch of what looks like HTML (possibly CSS?) is sent to standard output. Even if I ignore the output, I still cannot find anything in any error logs, and the no entry is made in the log table associated with the log schema. Am I being stupid that this should work as simple as this, or is there a lot more involved? Surely I am not the first person that needs to do something like this?

Hi,

I recently had to create a email service using a cron job and scriptcase. When you use a blank app there are still some libraries that get called where the paths will not work properly.

Disable security and enable direct call on the page. Otherwise if you try to call it on the command line you will see a bunch of html containing an error.

All the changes below will need to happen on the server you deploy your project to.

Just a note wherever you see “/path/to/deployed/scriptcase/site/” below that is the path to where the _lib file is located. So if your is located in “/www/my_site/” and inside the “my_site” folder is the “_lib” file then you put “/www/my_site/” wherever “/path/to/deployed/scriptcase/site/” apears.

Go into your my_blank_app_name folder then into my_blank_app_name.php and change the path to only be “index.php”.
Then go in to the “index.php” file and look for the following:
/*
$str_path_apl_url = $_SERVER[‘PHP_SELF’];
$str_path_apl_url = str_replace("\", ‘/’, $str_path_apl_url);
$str_path_apl_url = substr($str_path_apl_url, 0, strrpos($str_path_apl_url, “/”));
$str_path_apl_url = substr($str_path_apl_url, 0, strrpos($str_path_apl_url, “/”)+1);
$str_path_apl_dir = substr($str_path_sys, 0, strrpos($str_path_sys, “/”));
$str_path_apl_dir = substr($str_path_apl_dir, 0, strrpos($str_path_apl_dir, “/”)+1);
*/

This is where scriptcase tries to dynamicly find the path but this only works when calling the page from the browser. If you want to call it from a cron job or directly on the command line comment that code out and just add:

$str_path_apl_url = "/path/to/deployed/scriptcase/site/";

Then go down and update the paths for the following varaibles:
/*
      $str_path_web          = $_SERVER['PHP_SELF'];
      $str_path_web          = str_replace("\\", '/', $str_path_web);
      $str_path_web          = str_replace('//', '/', $str_path_web);
*/

Replace with $str_path_web = "/path/to/deployed/scriptcase/site/";

/*
$this->root            = substr($str_path_sys, 0, -1 * strlen($str_path_web));
*/

Replace with $this->root = "/path/to/deployed/scriptcase/site/";

/*
      $this->path_link       = substr($str_path_web, 0, strrpos($str_path_web, '/'));
      $this->path_link       = substr($this->path_link, 0, strrpos($this->path_link, '/')) . '/';
*/

Replace with $this->path_link = "";

After updating all those variables you will have to update the paths with them as needed.
To give you a idea this is what my paths looks like:

  $this->path_botoes     = $this->root . $this->path_link . "_lib/img";
  $this->path_img_global = $this->root . $this->path_link . "_lib/img";
  $this->path_img_modelo = $this->root . $this->path_link . "_lib/img";
  $this->path_icones     = $this->root . $this->path_link . "_lib/img";
  $this->path_imag_cab   = $this->root . $this->path_link . "_lib/img";
  $this->path_help       = $this->root . $this->path_link . "_lib/webhelp/";
  $this->path_font       = $this->root . $this->path_link . "_lib/font/";
  $this->path_btn        = $this->root . $this->path_link . "_lib/buttons/";
  $this->path_css        = $this->root . $this->path_link . "_lib/css/";
  $this->path_lib_php    = $this->root . $this->path_link . "_lib/lib/php";
  $this->path_lib_js     = $this->root . $this->path_link . "_lib/lib/js";
  $this->path_lang       = $this->root . "/_lib/lang/";
  $this->path_lang_js    = $this->root . "/_lib/js/";
  $this->path_chart_theme = $this->root . $this->path_link . "_lib/chart/";
  $this->path_cep        = $this->root . $this->path_prod . "/cep";
  $this->path_cor        = $this->root . $this->path_prod . "/cor";
  $this->path_js         = $this->root . $this->path_prod . "/lib/js";
  $this->path_libs       = $this->root . $this->path_prod . "/lib/php";
  $this->path_third      = $this->root . $this->path_prod . "/third";
  $this->path_secure     = $this->root . $this->path_prod . "/secure";
  $this->path_adodb      = $this->root . $this->path_prod . "/third/adodb";

The downside of this is that now anyone can call this page using its name in the URL. To avoid this you will have to update more variables. In our case the code of the php file will very rarely need to be updated but if you will have to update the code in the php file often this approach might not be usefull.

If you want to move the whole blank app to a diffrent folder on the server where users on the frontend wont be able to call it change the following.

Look for the:
if (!function_exists("sc_check_mobile"))

Inside it you will see an path that fails. Replace the start of the path with “/path/to/deployed/scriptcase/site/”.
Keep the rest of the path connected to it just replace the front of the path. (The rest of the path should be something like “_lib/lib/php/nm_check_mobile.php”.

Then look for the following if’s:
if (!function_exists("SC_dir_app_ini"))
if (!function_exists("NM_is_utf8"))
and do what you did for the if above where you just replace the front of the path.

Then look for the following code:
<META http-equiv="Expires" content="Fri, Jan 01 1900 00:00:00 GMT"/> <META http-equiv="Pragma" content="no-cache"/>

Below it there will be some broken paths. Update them to work. I can’t remember what they looked like before I updated them but this is what they look like now:

<link rel="shortcut icon" href="<?php echo $this->root . _lib/img/scriptcase__NM__ico__NM__favicon.ico?>">
                <script type="text/javascript" src="<?php echo $this->Ini->path_prod ?>/third/jquery/js/jquery.js"></script>
                <script type="text/javascript">var sc_pathToTB = '<?php echo $this->Ini->path_prod ?>/third/jquery_plugin/thickbox/';</script>
                <script type="text/javascript" src="<?php echo $this->Ini->path_prod ?>/third/jquery_plugin/thickbox/thickbox-compressed.js"></script>
                <link rel="stylesheet" href="<?php echo $this->Ini->path_prod ?>/third/jquery_plugin/thickbox/thickbox.css" type="text/css" media="screen" />

That should be everything.
If you see any other html errors inside the html there should be some kind of error. That’s the way scriptcase handles the errors by printing it to a html body. Had this happen a lot when I started working on creating API’s in scriptcase.

@jaques Thank you for the detailed response. I will give this a go over the next couple of days.

I am more of an enterprise app developer than a web developer, so I do have one (potentially stupid) question… Even though this is running as a cron job, will SC still create a session when the app runs or is access to session variables just going to fail, but execution continues.

The reason I ask is that a couple of functions in the internal libraries I want to re-use expect some session variables to exist. I could easily have the blank app set these, but that is only going to work if the session is created. If there is no session I can change the library functions to check if the session variables exist (isset()) and if they don’t, I can set some default values within the functions - I just need to know which way to go on this.

Thanks for your help. Cheers.

I am not 100% sure if the session is still created. So I will just say try the above changes and run the command to call the PHP file and see if it brings back any errors.

We use a linux server so the command for me to call it is:
cd /file/path/ && php my_file.php

You have to call the php file from within the folder else you will get another error.