PHP-Resources

An Android like syntax for getting static resources.

Notice Oct 14, 2019

This miight be in a useable state. I have some testing & fine-tuning to do before I really think it's ready for public consumption. I just think things are messy right now and needs a refactor. It's not currently in a state that is easy to maintain.

Install

CLI

composer require 'rof/resource': "dev-master"

in your composer.json:
"require": {
    "rof/resource": "dev-master"
  }

Usage Examples:

R_init('/path/to/resource.json', '/another_path/to/a/resource.json','/and/the/extension/can/be/wrong/AsLongAsItContainsValidJson/whoops_resource.jnog');

$errorForUser = R("error.db_connection_failed.public");
$errorForDev = R("error.db_connection_failed.dev");

$sillyString = R("string.something_silly");

$imagePath = R("image.favicon.path");
    echo file_get_contents($imagePath); //to print the content of the file
$imageUrl = R("image.favicon.url");
$alt = R("image.favicon.alt");
    echo '<img src="'.$imageUrl.'" alt="'.$alt.'">';
or
$imageHtml = R("image.favicon.img_tag");


print_r(
    R_all() //returns all the resource declarations as an array
); 

// NAMESPACE SCOPING
//
//
R_ns('namespace');
$scoped = R("string.scope_test"); 
R_ns();//to reset it
$fqn = R("namespace.string.scope_test");
//thus $scoped===$fqn

Sample json resource file:

{
    "string": {
        "something_silly":"I like to write silly codes. Silly silly silly."
    },
    "error": {
        "db_connection_failed":{
            "dev":"The database connection failed to be created.",
            "public":"There was an internal error on the website."
        }
    },
    "image": {
        "favicon":{
            "path": "/am/dumb/path/favicon.ico",
            "url":"/am/dumb/url/favicon.ico",
            "alt":"site logo",
            "img_tag":"<img src='/am/dumb/url/favicon.ico' alt='site logo'"
        }
    },
    "namespace": {
        "string": {
            "scope_test": "success"
        }
    }
}

Future Plans

No firm development plans at this time. It's a little side-project for fun and maybe I'll use it too.
Email rsutman@gmail.com if you want to work on this project. Or I guess, do a pull request and I can try to learn how that works.

Some Ideas I have are:

  • values wrapped in objects, so the rest of the resource information can be referenced relative to any retrieved value
  • automatic pre-pend for certain lookups, like 'path' could prepend with the home dir or 'url' could prepend with the https://domain.whatever
  • Delivery of resource files, including caching and setting headers
  • HTML representation of resource files, such as <link rel="stylesheet" href="/am/dumb/style.css">
  • internal lookups. For example, the img_tag declartion above could become: "img_tag":"<img src='{{this.url}}' alt='{{this.alt}}'> or... something like that.
  • Grouping of HTML representation... like... R_html("style.main","style.buttons","style.photo_grid"); would... create a file style-buttons-photo_grid-[timestamp].css with the content of all three and return `
  • validation of resource prefixes, including throwing an error if a prefix is used that is not valid.
  • configurable error handling. Currently Exceptions are thrown. Perhaps error_log could be used instead???
  • SharedPreferences style thing (but that should be a whole other git repository)
  • an autoloader for PHP files??? Probably outside the scope of this package.
  • Error and exception handling. If an error is logged or exception handled, perhaps a ressources-gen.json file could be created and amended to list different error messages and... maybe arrays of stack traces??? Sounds really cool. May be outside the scope
  • dynamic (php-driven) global resources. LIke... R('db.pdo') or maybe R_dynamic('db.pdo') at least during the alpha phase of the feature. Either do {"db":{"pdo":"get_my_pdo_object"}} and R_dynamic would ultimately call get_my_pdo_object(), a web-dev defined function and that would return a pdo object. OR have a script call R_set('db.pdo',$myPdoObject = new PDO(...)) (forgive the ugly inline-ing of the instantiation.)
  • Secure settings, requiring a password to retrieve. You have resources.json defined with the value "db": {"password": "encryptedDatabasePassword"} and the actual database password (once decrypted) would be something like KNEWl;kn455sadf&Y)(&_*(#@N j;lfweP(FSD@#YERWJA jI{}|\\+_+Tqiojklsadj;lakfsjdKNEJ. The gist is... the databse password is NOT memorable and it is NOT written down. That crazy long string is encrypted and the encrypted value is stored in the resources.json file, then a decryption key can be used to retrieve. But... furthermore, you can skip ever writing down the decryption key, keep it in your brain, and make hashes of it for the hash-table. R_secure('db.password','MyMemorablePassword817692BeMoreSecure'); R_secure would then do something like:
        $encrypted = R('db.password'); 
        $decrypted = open_ssl_decrypt($encrypted,$method,'MyMemorablePassword817692BeMoreSecure');
    
    Additionally, it could use an internal hash table. Then rather than passing in the MyMemorablePassword.... to R_secure(...), we could pass in a hash of the password, which then looks up the encryption-key (MyMemorablePassword...), which then is used to decrypt the actual database password, and then the db password is returned. Then set it so a particular hash of MyMemorablePassword... can only be used once per request. This way, there'd be a hash table of decryption keys, but you wouldn't know which decryption key goes to which encrypted value. Idk if this is a good idea or not. I'm just thinking.

These are ideas. They're good ideas, probably. Who knows if I do it. But now that I laid out my thoughts, I'm excited to work on it... even though it's not a priority! lol