SMVC restructure

I've given the framework a bit of a restructure so it main files are outside of the web root by default and the only files that should be inside the web root are the templates, .htaccess and index.php.
so the structure is now like this:
app
	Controllers
	Core
	Helpers
	Language
	logs
		error.log
	Models
	Modules
	vendor
	views
	composer.json
public_html
	templates
		default
	.gitignore
	.htaccess
	index.php
	licence.txt

From the index.php the starting path would be:
$smvc = '../';

The vendor path would be
if (file_exists(SMVC.'app/vendor/autoload.php')) {
    require SMVC.'app/vendor/autoload.php';
}

I've also adjusted the view class and url helper to make the paths more flexible.
This would mean all public files (templates) would be in the web root all classes would be outside the web root.
The logger class has been changes since it would no longer be able to serve html errors they would be stored in app/logs/error.log above the document root.
This kind of setup needs to happen, it's a basic security practice. I'm very late in changing this.
First off is there any objections to this?
Additionally should this be a sub part update 2.2.1 or warrant a full version increase? personally I think 2.2.1 would be sufficient no new functionality has been added.
Another area I'm not 100% on is Modules. They may need to be in the web root as well so any modules containing css can be loaded but at the same time they will contain classes so should be above the root! will require some thought on this one.
I haven't pushed this up yet I'm waiting to get your thoughts on this.

Thanks Dave. This is a good change. Personally, I think it's should be 3.0, since the core structure is changing and further functionality will be based off of this new structure.

Yeah @volter9 said the same thing for 3.0 it does make sense. The only issue I need to solve now is getting modules css to work in the public when placed above it.
It's been suggested have 2 module folders
1 - above the root containing the module classes etc
2 - mobiles folder in the root for it's css/js files
I'd rather have a single place for the module so it's standalong and plug and play so to speak.

@daveismyname I also think version 3.0 describes it best. According semver.org you change a lot of things:

Given a version number MAJOR.MINOR.PATCH, increment the:

MAJOR version when you make incompatible API changes

And with your changes you break the backward compatibility.

I wonder how this will effect ftping to shared servers? I currently use git ftp which pushes my whole folders changes to the server. Perhaps this would mean that I would have to store a public_html folder in my git repo?
Thoughts?

I think you would have the public_html folder in your structure, that's what I have typically.
https://www.dropbox.com/s/hfbl0dzcem82ob6/Screenshot 2015-11-29 11.04.04.png

I cant see that link but your comment answers my question :+1:

Why Vendor in the app?
Personally, I would prefer like this (personal vision :)
app
    Controllers
    Core
    Helpers
    Language
    logs
        error.log
    Models
    Modules
    views
        templates

public
    assets
        templates
            default
                css
                js
        modules
            some_name
                css
                js
    .htaccess
    index.php

vendor
.gitignore
composer.json
licence.txt

Obviously should be version 3.0

It's going to be 3.0
I'm happy with that structure only question why is there a templates folder in views?

Everything looks solid, and will definitely make the framework better

By mistake, it should be in the app :)
I have a question about Models
Currently, we use model like this:
$this->blog = new \Models\Blog();

$data['posts'] = $this->blog->getPosts();

Is it possible to be this way?
use Moldes\Blog;

$data['posts'] = Blog::getPosts();

? :)

Maybe a good idea to rethink the models too. And maybe make an extra service layer for business logic. And maybe also let the models be the actual models (classes with database data mapping) so you could use PDO FETCH CLASS to let the record data map into the models. (Database fetch logic in service classes).

@mickacz  The only issue I see with that is then there is no difference between the way we use helpers and the way we use Models?

What @mickacz is about mentioned, shouldn't we avoid too much public static? I read it somewhere saying its bad design?

@mickacz I don't think it is with the models extending the base model

Dear Dave,
I think this new structure will be an issue for me.
My serveur is used to serve multiple apps based on smvcf.
Today, everything is fine, I have one directory per smvc.
www/
smvcf1/
smvcf2/
...
Then I access my apps :
http://mysite/smvcf1/
http://mysite/smvcf1/
...
Moving to the new architecture, how this will look like ???
How can I differentiate the multiple app/ dirs if they all go beneath www/ ?
Please advise.
Laurent
PS / I do not have a security issue having all the files in one public dir. This is how it is done for common CMS (Joomla, Wordpress). Files are anyway not directly accessible.

@yeshelolo you can put them all in one place still in the index.php file is a variable for the path to the app folder that would just be ./ instead of a ../ that way it can all reside inside the public folder as you do normally.
@tomvlk I'm interested in what you're suggesting, but not sure I follow 100% could you explain a little more on your idea?

@daveismyname the service layer is a bit explained here: http://www.aliaspooryorik.com/blog/index.cfm/e/posts.details/post/oop-terminology-part-viii-service-layer-156
In the model you define your variables that your database entry has.
In the service class you define the CRUD operations for the model and with optional more methods for getting with specific id's and stuff like that. So your SQL will be executed from the service layer.
Another good graph that explains: http://i.stack.imgur.com/hlhOw.png

@tomvlk thanks I'll have a read of them later.

@tomvlk We use a service layer at work, but that is sans-framework. Im not exactly sure that a service layer is the right idea for a simple Framework such as SMVC. But definitely interested to see how you would go about implementing it. Sounds like something that could work really well.

I've already used it in combination with PDO_CLASS fetch and simplemvc.  But thats really not that much work if you let the service classes extend one abstract service class with most of the logic.

Actually I've always wondered why frameworks have almost the same default structure, like codeigniter,
For me, an application(implementation) has models, controller and views, so maybe they should be inside the app folder , the rest of the files like helpers, core, etc... should be on their respective folder. I think separating the framework from the implementation is the logical step to do.
I would like to hear your thoughts.
app
    Controllers
    Models
    Views
system
    Core
    Helpers
    Language
    logs
        error.log
    Modules
    vendor
    composer.json
public_html
    templates
        default
    .gitignore
    .htaccess
    index.php
    licence.txt

I like it, but just a detail, I supose you use public_html name because is the default web folder in some web servers, but I think that nowadays _html suffix is incongruent, maybe public is enough.
Is only a detail, but public_html is longer than public and really this folder will contain other files as css, images, js...
By other hand I'm agree with geomorillo with separate system files from app files. Is interesting for framework updates and to share the system folder between projects.

@daveismyname  on my host I will still need to be under the public_html folder, how do I structure it.

@jimgwhit you can put them all in one place still in the index.php file is a variable for the path to the app folder that would just be ./ instead of a ../ that way it can all reside inside the public folder as you do normally.
@geomorillo that structure looks fine but I would have Modules inside the app also have another modules folder inside public for the module specific css / js files
@rtorralba the public_html folder is dependent on your setup some will be public_html some will be htdocs some may be something else it should not make any difference. Lets call is public then it can be changed as needed on implementation.
Any objections to a app / system setup? seems logical.
The final result will be flexible enough so you can place all files inside your public directory should you need that.

@daveismyname also this
public_html  //  /is this the hosting servers folder where things go?
    templates
        default
    .gitignore
    .htaccess
    index.php
    licence.txt

Would keep you from having more than one site I could see
public_html
    public  // could be site 1
        templates
        default
       .gitignore
       .htaccess
       index.php
       licence.txt
    public  // could be site 2
        templates
        default
       .gitignore
       .htaccess
       index.php
       licence.txt

You are saying to put files directly in what is the htdocs folder on some host.
htdocs //  this this the hosting servers folder where things go? where would templates for site 2 go?
    templates
        default
    .gitignore
    .htaccess
    index.php
    licence.txt

Very confusing.
Also please give instructions on how to still put the framework under htdocs, My host still requires that.  The tricky part to me is getting paths right.
On godaddy I have:
public_html
    mysite
        app
        public
        vendor
        index.php
        other files

In other words the standard way you normally upload to host.  Just please tell me how to still do this with new version, and how those paths would be resolved.

We need to agree on the structure before that can happen. Once that's agreed of course it will be documented I would not leave out such an important step.
What I'm saying is you will be able to have a project folder in your public folder (public_html / htdocs / public / whatever) then place the folders within that such as app / system and the root files.
Then for the people that want to place the app / syste, files above the document root that will be supported too.

I would like to test on godaddy, do you have a zip to send to<EMAIL_ADDRESS>I just get very confused on resolving paths.  Look at my godaddy structure above, pretty standard for a shared host. I would probably need
newsmvc // folder above public_html
    folders and files you said goes above
    public_html
        smvcpublic
            public
                 files you said goes in public

I can't just put public under public_html, I have 2 sites.  I can't have 2 folders named public, what am I missing.  For diagram above what would RewriteBase /newsmvc/ be changed to?  I can't see it being RewriteBase /public_html/smvcpublic/public/

An idea, can you completely set up all on a hosted server like godaddy, get it working, then zip it and make a copy available for download, so everyone would see how all the new paths resolve.  I have spend 5 hours before getting paths right, it's not fun.

@jimgwhit yes happy to, I'll model this on the structure proposed above.

Of course I am referring to the Ver 3 when released.

I like @geomorillo's way of doing it, keeping the app and system files separate.

yeah just got ensure the paths work will require a little tweaking here and there and looking at getting composer to autoload from both directories.

@daveismyname I made an important observation, Even laravel installs with composer under (htdocs, www) on a local development machine.  It's not till you upload it to production server that they say to put stuff a level above htdocs.  This being the case, how will the new version work on my development server? I wouldn't have any idea how to separate stuff out.  I currently use a bitnami wamp stack. And all development falls under the htdocs folder.
Sorry if this is getting confusing, but please think about maybe having the framework for development still under htdocs, with instructions on how to separate once uploading to a production server / host.  I'm not advocating laravel here, but that's the way they do it, give it a try yourself for testing purposes.

for local setup all you do is place your files in your project folder like this:
app
    Controllers
    Models
    Views
system
    Core
    Helpers
    Language
    logs
        error.log
    Modules
    vendor
    composer.json
templates
    default
.gitignore
.htaccess
index.php
licence.txt

inside index.php the $smvc var will be simply:
$smvc = './';

then on production server it's:
app
    Controllers
    Models
    Views
system
    Core
    Helpers
    Language
    logs
        error.log
    Modules
    vendor
    composer.json
public_html
    templates
        default
    .gitignore
    .htaccess
    index.php
    licence.txt

and
$smvc = '../';

@daveismyname
app
    Controllers
    Models
    Views
system
    Core
    Helpers
    Language
    logs
        error.log
    Modules
    vendor
    composer.json
public_html
    templates
        default
    .gitignore
    .htaccess
    index.php
    licence.txt

How would or could this work if you had 2 sites, that folder structure would force putting template files from more than one site together.  You need another folder.
Like:
public_html (www or htdocs on some)
    site1
        templates
            default
    .    gitignore
    .    htaccess
        index.php
    licence.txt
    site 2
        templates
            default
    .    gitignore
    .    htaccess
        index.php
    licence.txt

same with this
app
    Controllers
    Models
    Views
system
    Core
    Helpers
    Language
    logs
        error.log
    Modules
    vendor
    composer.json

it would need to be
upperlevelfolder1 (site 1)
    app
        Controllers
        Models
        Views
    system
        Core
        Helpers
        Language
        logs
            error.log
        Modules
        vendor
        composer.json
upperlevelfolder2 (site 2)
    app
        Controllers
        Models
        Views
    system
        Core
        Helpers
        Language
        logs
            error.log
        Modules
        vendor
        composer.json

Otherwise you have files from 2 or more sites combined in the same folder.

And this is where resolving paths can get hard to do.

yes for multiple projects you would place each in a separate folder, to use different folder names that can be accomplished. The finer details on that I'm testing still.

I am wondering how this will effect git ftp push.
I use git for my websites and use git ftp push for moving my changes live. This works really well because everything is in the same folder and git is based in that folder. and I can push it to a folder on the server.
How do others manage their ftping?

I still ftp with plain old ftp so I can't answer that at least not yet.

Yea OK I could do plain old ftp but git ftp is really nice it picks up your commits and only pushes those files! that way you dont have to remember what you have changed and also it excludes files in your gitignore (like config!)

@daveismyname please email me a  zip file so I can start testing or post a link here for us to download Thanks.

I have to build this first I'm working on it.

I  meant when you had something ready, thanks.

Nearly ready, I have the framework in the new structure working on the root of a domain and also 2 more installs in demo1 and demo2 all system/app files above the document root.
Need to do more testing but looks all OK so far.

demo1 and demo2 are distinct projects and public_html/demo1 and public_html/demo2 public files for this projects?

yes the demo 1 and 2 above the publc_html contain a app and system folder for the project.
Inside public_html is the templates and index.php .htaccess files

This is your proposal for the standard structure or is a specific example?

for the proposed structure with an example of using multiple projects on a single domain, normally you would have a single project per domain.
This structure is based from https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-161145544

Then how you put the projects in a git repository (app and public folders are in different folders)? I supose that is a project with multiple smvc instances, no?

For the sake of a repo can you have a generic public folder for the templates and front end files and the app and system folder outside the public folder?

Why not make it with the following structure, protecting non public folders,  if are a different projects?

demo1
-- app
-- system
-- public_html
-- index.php
demo2
-- app
-- system
-- public_html
-- index.php
main
-- app
-- system
-- public_html
-- index.php

I supose there ara a restriction that i didn't read

the index.php needs to be within public_html the app and system folder are like this in my new setup.
In side the public folder will be:
templates
   index.php
   .htaccess

my screenshot had multiple folders only to show how it could work with multiple projects on the same domain.
When using a single domain and a single install it would simply be

Okay but what is the folder structure when everything will still fall under HTDOCS or www? Like some shared host will still require?

@daveismyname did you look at laravel like I asked you to there you only go above wwww / htdocs in production not in development. So definitely need examples for the various situations.

@daveismyname  And how in the world will composer install this? On development machine there is no way that folder structure works , on development everything has to go underneath htdocs.

@daveismyname Okay but what is the folder structure when everything will still fall under HTDOCS or www or public_html depending on shared hostt? Like some shared host will still require? Please give a good example of this also and how to resolve paths.
Also example htaccess and config.php examples please for various setups.

I've posted examples above, with 3.0 the paths are flexible that can be defined within index.php so you can move them as desired.
For instance to have the app and system folder above the docroot in a folder called myproject you would have this in index.php:
$smvc = '../myproject/app/';
$system = '../myproject/system/';

to have app and system inside your public root then its
$smvc = 'app/';
$system = 'system/';

it's flexible.
Both config and .htaccess remain unchanged the paths in those are relative to the url / for the root and /projectfolder/ for when inside a folder.

@daveismyname did you look at laravel like I asked you to there you only go above wwww / htdocs in production not in development. So definitely need examples for the various situations.

You should give more thought to your wording that sounds like you're giving me an order. I don't work for you, I give my time freely for this project please be respectful.
This has been addressed above.

@daveismyname And how in the world will composer install this? On development machine there is no way that folder structure works , on development everything has to go underneath htdocs.

the same way as you do now. All composer is doing is downloading the files. There has always been an element of configuration needed 3.0 will be no different, the htaccess and config file will need setting up along with htaccess.
I have this working both on a local server under php 7 and on a live server under php 5.6 so it is indeed working.
Honestly I'm not going to leave users stranded with a version that does not work. I have projects both on a dedicated server and on a shared server so I understand the need for both cases.

@daveismyname You have to know I didn't mean any dis-respect, I meant to maybe get ideas form laravel, yii, etc. You have been very good at resolving problems in the past.

I apologies if I came across as angry it's been a long day let's not say anymore on it.
I'm 90% sure this new structure is good to go I'm going to do more tests and tryout an average project before I do a beta release of this for wider testing.

Really good job you are doing dave, please rest a bit dont overwork, is bad for health cheers

thanks I appreciate the support :)

Are you going to create a new branch on github for this new version?

I was going to release it as a new release, to be honest I don't use github enough. I don't know about branches I'll be sure you look at them.

A beta first is a great idea. Please give a link here in this issue #222 when you have it.  But like @geomorillo said rest some, no hurry.  I'm sure all of us realize you need to test first.

I think it should be:
app
system
public
vendor
.gitignore
composer.json
licence.txt

Otherwise it will not make sense
Look at the structure of mako-framework, various skeletons of Slim 2-3, Laravel. None of them holds inside public .gitignore or vendor from composer inside system.

I dont see why the framework has to follow those structures, could you explain why they should be outside? maybe im not getting something.

I don't think they NEED to be but after a few tests I actually like it that way. From a paths perspective it makes it a lot easier.
With the dynamic paths it's still easy to change should to want to it's got a :+1: from me.

Any way we can get a zip of what you go so far for testing?

Yeah I'll do a bit of cleanup and get something up in a few hours.

great, already on the beta branch

OK I've got a 3.0-beta branch setup with 3.0 for testing purposes only this should not be considered as stable.
I've created a temp readme file detailing the major changes and how to get up and running with it. I stress again this is very early stage beta testing please bear that in mind.
https://github.com/simple-mvc-framework/framework/tree/3.0-beta

@daveismyname  what would $root = '../'; be change to if all is going under public_html?

./ should do it.

So
$smvc = '../app/';
$system = '../system/';
$root = '../';

To
$smvc = 'app/';
$system = 'system/';
$root = './';

How about the error log, how can it stay under public_html?

Yes
It's inside of system folder so it will be in your case.

I made this route
Router::any('home', 'App\Controllers\Welcome@index');

tryed
$smvc = 'app/';
$system = 'system/';
$root = './';

then tryed
$smvc = './app/';
$system = './system/';
$root = './';

url I tryed
http://localhost/fm3/home

both trys above I get
Not Found

The requested URL /fm3/home was not found on this server.

I will keep trying to resolve the paths any tips?

Have you got /fm3/ in your config.php file and .htaccess?

yes
define('DIR', '/fm3/');

and
RewriteBase /fm3/

I can't do that on host.

Re tryed all these
$smvc = '../app/';
$system = '../system/';
$root = '../';

$smvc = './app/';
$system = './system/';
$root = './';

$smvc = '/app/';
$system = '/system/';
$root = '/';

$smvc = 'app/';
$system = 'system/';
$root = '';

$smvc = 'app/';
$system = 'system/';
$root = './';

@jimgwhit
I think you should try with:
define('DIR', '/fm3/public/');
RewriteBase /fm3/public/
http://localhost/fm3/public/home
As index.php file is now located in 'public' folder.

I got it,  Insructions say
for a localserver place the files within public in the root of your project (move them up a directory so they are with app and system)

I didn't know I was to move templates, I finally got welcome page.
this is what worked
$smvc = 'app/';
$system = 'system/';
$root = './';

Ok I will continue on to more test, that's -- still confused on error log.

I figured out the namespace for models is namespace App\Models;
But so far I did quick test and I am getting database results.  @daveismyname keep us posted.  Sorry about the template thing, I moved it up even with other folders, was that correct?

Yes that's correct to have them working in the same folder under the public root or when on a localserver.
For the errorlog to see errors you can either go to the log directly in system/logs/error.log or go to system/Core/Logger.php and turn display to true. That will print errors to the screen when they happen, they will be to recorded in the error.log

a quick video going over the major changes and getting setup https://www.youtube.com/watch?v=28l8lJz-oRM

:thumbsup:

Got it working on development With all under htdocs.
Then tryed the move it up thing here is folder structure:
C:\Bitnami\wampstack-7.0.0-0\apache2
......................................tjupfold
..............................................app
..............................................system
..............................................vendor

Folder structure for other files:
C:\Bitnami\wampstack-7.0.0-0\apache2\htdocs\tjtest
..................................................public
..................................................the other files

In config.php I tryed
define('DIR', '/tjtest/public/');
and
define('DIR', '/tjtest/');

in htaccess I tryed
RewriteBase /tjtest/public/
and
RewriteBase /tjtest/

In index.php I tryed
$smvc = '../tjupfold/app/';
$system = '../tjupfold/system/';
$root = '../tjupfold/';
// with this I get the message
Please install via composer.json

Install Composer instructions: https://getcomposer.org/doc/00-intro.md#globally

Once composer is installed navigate to the working directory in your terminal/command promt and enter 'composer install'

and tryed
$smvc = '../../tjupfold/app/';
$system = '../../tjupfold/system/';
$root = '../../tjupfold/';

If I run composer with above folder structure, It won't install correctly.
Any help here?

i cannot understand your folder structure specify your url and a clear folder structure.

That's the structure that is actually on the computer, url should be
http://localhost/tjtest

The 3 folders you said to move is now under apache2\tjupfold like
apache2
htdocs
.............tjtest
.............public
..............tjupfold
.........................app
.........................system
.........................vendor
..........,,

if tjtest is your project what is tjupfold?
If you running this locally you don't need public at all remove it completely. You structure looks like you have tjupfold inside public then have app,system,vendor under that.

No tjupfold is above htdocs.
You have apache2\htdocs where sites normally go.
I tryed to create the folder tjupfold under apache2 so the 3 folders would be out of htdocs.

Your first image above with demo is what I'm trying.
Does the upper folder name have to be same as the folder name that is in htdocs?

ha you've update you post it was like this when I read it:
apache2
htdocs
.............tjtest
.............public
..............tjupfold
.........................app
.........................system
.........................vendor
..........,,

right in this case you still don't need public so delete it have your templates / index etc inside tjtest
then
$smvc = '../../tjupfold/app/';
$system = '../../tjupfold/system/';
$root = '../../tjupfold/';

Will give it a try, meanwhile can (when you get a chance) do a video on the move it up thing?

Sure.

Holy freaking mackerial that worked.
So is this correct. Set it up on local for development like in video you did, then do the above last reply for production?

yes exactly, you can have it all together for development then in production more the folder above the root

And of course is a host doesn't allow the up thing, it would still work as usual.

yes I still need to test across different cases just to make sure but I'm fairly certain it's flexible enough to cope.

Oh I had to change in Url
public static function templatePath($custom = TEMPLATE)
    {
        return DIR.'templates/'.$custom.'/';

    }

to
public static function templatePath($custom = false)
    {
        return DIR . 'templates/';
        //return DIR.'templates/'.$custom.'/';

    }

and in header I do
<link href="<?php echo Helpers\Url::templatePath(); ?>default/css/style.css" rel="stylesheet">

Was getting two // after templates.

Get some rest!

No one else has any testing results?

I will want to do some testing to work out how got FTP will cope with this change. Especially a change in folder structure when changing between development and production.
I am assuming that you can run the production setup in local xamp servers? ( have the folders above htdocs?)

*git ftp

yes the paths are updated to point above htdocs.

I'll try give it a whirl tonight with git FTP then to see how that will work.
Dave if you like I can teach you how to use that so you have a better process for pushing to production!

@daveismyname  and @woodsy1 I have tested on local dev both ways, having all under htdocs, it's htdocs on my machine not public_html, and having app, system, and vendor a level higher than htdocs.  Both setups work.  I also tested on godaddy shared hosting, so far it works.  But you should be able to develop the usual way and just do a separation when you upload to production.  But a separation isn't required, it still works either way. Doesn't git put the files where you tell them?  And where is a tutorial on that Git stuff you are talking about?

I've recorded a video covering moving folders above the document root https://www.youtube.com/watch?v=hQiZtVd34d0
Thanks for the offer yes I'd like that.

The last video was good, oh boy another video. I got it solved, but am going to watch the video anyway.

Local it works for me. On the server I'm going to test it. Very good @daveismyname! :thumbsup:

@daveismyname video 2 was good. Until now, I didn't know that was possible on godaddy, but there are host where all has to be under the public_html.  So thanks for ensuring flexibility.

@Jimgwhit thanks for that summary. My concern here is that with a potential
change in folder name from htdocs locally to public_html on the server git
FTP might have issues.
I'll test and see
On Dec 6, 2015 8:10 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

@daveismyname https://github.com/daveismyname video 2 was good. Until
now, I didn't know that was possible on godaddy, but there are host where
all has to be under the public_html. So thanks for ensuring flexibility.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-162247514
.

He uses sublime text editor. I presume brackets.io

Prefer*

@woodsy1 does everything I need and goes it quickly, what's better about brackets? I really like the integrated FTP, project switcher plus I've got snippets written for sublime text so helps speed writing code.

@jimgwhit I'm really busy now, I don't have much time. I think that everything in the system folder should go to the separate repo smvc/core and be required in composer.json for project template. I never really liked everything in the app directory.
My suggestion would be to separate core of framework to separate repository and publish it as separate package. There would be another smvcf package called smvcf/project which would be project template which would consist out of two folders: app/ and public. There's also would be files like composer.json with required SMVCF core package. That's where unit testing comes handy.
That's my opinion and I'm not forcing it, therefore I'm not really into discussing it's pros and cons.

@woodsy1 what's the difference, before it was still htdocs wasn't it?  I develop on a bitnami stack and it's htdocs. But on godaddy it's public_html.  That thas't changed.

The difference is that now we will have to store our root folder in the
repo so if we push to server (using git FTP push ) then the folder names
are difference and it would push a htdocs up instead of a public_html.
I'll do testing with it tonight.
On Dec 6, 2015 9:07 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

@woodsy1 https://github.com/woodsy1 what's the difference, before it
was still htdocs wasn't it? I develop on a bitnami stack and it's htdocs.
But on godaddy it's public_html. That thas't changed.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-162252383
.

The solution may well be to change the webroot of my local server to
reference a public_html.
On Dec 6, 2015 9:41 AM, "daniel wood"<EMAIL_ADDRESS>wrote:

The difference is that now we will have to store our root folder in the
repo so if we push to server (using git FTP push ) then the folder names
are difference and it would push a htdocs up instead of a public_html.
I'll do testing with it tonight.
On Dec 6, 2015 9:07 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

@woodsy1 https://github.com/woodsy1 what's the difference, before it
was still htdocs wasn't it? I develop on a bitnami stack and it's htdocs.
But on godaddy it's public_html. That thas't changed.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-162252383
.

@woodsy1 that doesn't make any since, if you are developing under a htdocs folder now, and host has public_html well how are you doing it now? Not to be rude here, but you are trying to over complicate it.  So you are telling me you can't even push now because of name conflicts?  There has to be a way, have you dug into the git docs?  People do this all the time, just look at the laravel forum, there people are developing under a htdocs folder, but manage to push or whatever to a live server / host.  There has to be an automated task for such a push.

@woodsy1 are you saying that you want the framework only to be available to people who's development server happens to have public_html as the folder that sites go beneath, and no one can develop if they fall under www, or htdocs?

@daveismyname we should take the comparisons of editors off this thread so to keep it on topic. I will create a thread on the forums with my thoughts to get the ball started :)
@jimgwhit When you have to preface your statement with "not to be rude here" it means your being rude ;) I am not overcomplicating things. I am trying to simplify things! When using git ftp I can type 1 command into my command prompt and push all my latest commits to my server without manually having to remember where they go or what I have changed.
The reason it becomes complex is because we no longer have a folder that everything sits under that we can put directly into the git repos. At the moment I have the entire folder sitting in a repo and it is easy but with the proposed design things will be above the web root which will mean that we will have to include the webroot folder in the repo as well. As I have said I havent tested anything yet so I am not sure how this will work (I will have time tonight to test).
There are 2 concerns I have that might be an issue for the automatic git ftp approach.

If the webroot folder on local dev is called something different to the server then it would put the files in a different location on the server.
If you have multiple sites in your local dev server. (I think its possible to exclude items from the repo when you select a folder but I will have to test it)

Again I havent tested anything yet I was just flagging this could be a potential issue for what is currently the best way of deploying to servers when developing with PHP. (Plain of ftp is far to prone to user error for me!)

@jimgwhit and of course not we are a community and trying to develop a framework that is suitable to all!

@woodsy1 OK, sorry if I mis-understood,  but I am just totally confused on what you are talking about. Yii, Laravel, and some other frameworks have done the out of public_html for a while now. How are these folks deploying? Since we know there is a way I don't see where there is even an issue on this, that has anything to do with SMVC. Ask yourself this if were using laravel, how would you achieve that task?

I don't use any of those frameworks so I don't know!
I don't know how it would be achieved and that's why I have raise the issue!
On Dec 6, 2015 2:47 PM, "jimgwhit"<EMAIL_ADDRESS>wrote:

@woodsy1 https://github.com/woodsy1 OK, sorry if I mis-understood, but
I am just totally confused on what you are talking about. Yii, Laravel, and
some other frameworks have done the out of public_html for a while now. How
are these folks deploying? Since we know there is a way I don't see where
there is even an issue on this, that has anything to do with SMVC. Ask
yourself this if were using laravel, how would you achieve that task?
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-162268619
.

Well, then we'll figure it out.

Dear Dave,
I went through the videos you made, thanks for this it explains well.
I like very much the KISS approach of the framework and in that spirit, I would like to continue to have everything in one single folder per app. I do not have any security issue here since my apps are not on internet. And this also make my life easier for eclipse PDT / Git / backups devs.
Even though, folders can be adjusted manually after framework download, it would be nice to deliver an installation package that is ready to go  for the 'all-in-one-folder' option. Would you consider providing that package in 3.0 ?
If not I can live without, I will jus have to tailor folders manually after each download.

Again, don't put config file in system folder :joy:

why?

system folder is read-only folder. config can dynamic change.
you should put config file in app folder.
P/s: In app folder, create helpers folder for user-helper files.
Like CodeIgniter structure.
I know you want build simple framework where developer can custom Core. But I don't think it's good all time.

I disagree it really makes no sense to put config in the app folder none of the are really read only they can all be written to. With that login the quote a few other file should be in the app folder as they have dynamic elements to them. I really don't see what benefit it would have placing it in the app folder.

@yeshelolo

Even though, folders can be adjusted manually after framework download, it would be nice to deliver an installation package that is ready to go for the 'all-in-one-folder' option. Would you consider providing that package in 3.0 ?

I'm working on a CLI utility so far it can make controllers, views and models. I'm working on an installer section to be able to set the config and htaccess files from the CLI having the ability for it to configure the structure paths too would mean you would not have to manually update your structure.
It's very much a work in progress but that could work for your need.

@yeshelolo you said:
Even though, folders can be adjusted manually after framework download, it would be nice to deliver an installation package that is ready to go for the 'all-in-one-folder' option. Would you consider providing that package in 3.0 ?

The thing is, you have folks who want in up a folder,  and others who wnat it the way it was.  @daveismyname has now made it so it works either way.  In the video, it took Dave all of two minutes to move some files, and change 3 lines in index.php.  I think what he's accomplished to please everyone in pretty darn good.  Just my two cents.
Also, I tested both ways, it did not take very long. I only had a little problem with resolving paths, but once you  do that once, there should be no problems.
In fact, the videos, and this issue # we are in right now completely covers what to do.

Thanks @jimgwhit I appreciate that, it's incredibly difficult to please everyone.

@daveismyname I tell you, everything is looking good, are you almost read to commit it to ver 3.0?
I'm sure you want to test more.  Oh, I don't use assets.php, I renamed it to assets.bak, I just call files the regular way like
<link href="<?php echo Helpers\Url::templatePath(); ?>default/css/style.css" rel="stylesheet">
<script type="text/javascript" src="<?php echo DIR; ?>public/js/jquery.js"></script>

and it works good. I guess I am confused about assets.php, because until I renamed it I got an error.  What is that file doing in the background?

I think that's due to the caching I've come across that too need to nail it down more, for now I've set cache to false as default.
I'm going to test more before I release to 3.0, it would be great to have the CLI utility ready at the same time too.
it's completely optional but can save time on common tasks.

Forgot to mention, I never got errors in ver 2.2 from that file. And what is a cli utility?

it's a change for 3.0 so the cache was not in 2.2 so that will be why :)
it's a command line script for instance to create a controller with some methods you would type:
php smvc make:controller Contacts index add edit delete import export

would create a controller called Contacts with 6 methods.

it's not in the beta yet in case you was wondering.

@daveismyname even after more test and tweaks, will the final ver 3.0 be close to the beta ver?  In other words the same install instructions as the two videos showed.
And is it fine to rename assets.php to .bak since I don't use it?

Yes to both questions, since your not calling it at all it doesn't matter what it's called. At this point I don't see the need to change the structure again it now caters for flexible paths.
I still haven't got around to looking into testing I'll cross that bridge when I get to it. But I don't want to change the structure again unless there is a genuine need for it.

The CLI would be good for some folks, but I can't believe folks can't just make a boilerplate controller, and do a simple copy paste and just rename it to new controller name.  That's what I do, and I imagine you also.

Yes I do that a lot, but manually creating it and the views is a lot slower then writing a line out on the CLI like I've said it will be completely optional, so you don't need to touch if you don't want to.

I will say this, you have come a long way since the very firsrt version, which I didn't use, I started using SMVC when you implemented the new router.

Indeed! it's been quite a journey learnt a lot on the way, still a lot to learn the beauty of programming! lol

@daveismyname a side note, what's funny is I have used cakephp, and they have cake bake which generates all code.  I didn't like that and still wrote all my own code.  The baked code needed too much modification.

I started out programming before Windows even existed in Dbase 3 in DOS.

I'm sure for a lot of people that will still be the case but nice to have the option.
Never heard of it, but I do remember learning the doc commands years ago though I never did anything with it.

My first computer, booted from a large floppy disk.

Get more rest.

Ofcourse, I making a idea. You can agree or not.
And I don't see CI put config file in system. CI storage all config file in application/config folder.

I just don't see what benefit it would give, when I looked at this repo it's in the system https://github.com/bcit-ci/CodeIgniter/blob/develop/system/core/Config.php

Dave that Config is diferent form the one inside /application/config/config.php, Still i think the config.php in smvc is fine where it is, because is not reallly a part of the implementation.

Ah I stand corrected :)

Why would anyone complain about where @daveismyname put the config file really. Next you will want Dave to pay your bills for you. Folks system is just another folder name config is fine there.

I guess you are right Dave. It's hard to please everyone.

I talk about where config file locate because I see image about folder structure https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-161915395
Multi app need multi config file. Using only same system (core) framework.
This structure like advanced template in Yii2

I understand where you're coming from now, but to have a multiple app it needs more then the config also the languages folder if it's using language files, routes file, error.log.
I hadn't considered sharing the system folder across multiple projects. I'm open to suggestions should this be a consideration?

@daveismyname really shouldn't each site be self-contained and not shared, that's just more efficient. If you start using a folder for multiple sites mass confusion can happen. And can't anyone figure out how to do this stuff on their own by pointing files to a certain place people please. And again why is it being compared to Yii. If someone really wants those features enough, why don't they just use Yii. SMVC is not Yii. Golie wiligers.

@nhymxu  you said
Multi app need multi config file. Using only same system (core) framework

If you carefully look at the folder structure in the second video Dave did you can point to a common system folder already just by playing with the
../../whatever/system

You're not thinking things through clearly. And you're kinda making things harder than they really need to be.

And the yek with Yii, we are talking about SMVC.

@nhymxu And another thing SMVC it's not that big you could have 10 sites with 10 different system folders and that would take up less room than a single installation of Yii or laravel alone, good gracious me has anyone even thought that much out yet? Sometimes you can really over think something and complicate it instead of making it simple and easy. I beg you stop the nonsense.

@nhymxu if we want to compare frameworks let's compare SMVC to Laravel, the way Dave has set up version 3.0 beta is like laravel, they also require separate sites and not shared folders, Laravel is the number one framework in the world, and Dave has set up deployment like laravel, so can we please leave things alone?

My opinion: I think multi app setup would complicate things a little, maybe for now we should not consider this.

@daveismyname I know I have no say so, but please don't do the shared thing, please have each site requires its own SMVC installation, that just makes sense, and will avoid mass confusion.
And I'm sure if @nhymxu needs help setting up a special case you would help him, I know you have gone out of your way to help me, and I thank you very very much

Thank you @geomorillo for coming in and sharing your thoughts too.

@jimgwhit you are spaming this thread with unnecessary comments and having
a go at people and their questions.
You have had your time and your help from Dave it is only fair you let
others have their chance too (even if you disagree with their questions)
If you don't have some constructive contribution to make perhaps it's best
if you back off for a while!
On Dec 8, 2015 4:55 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

Thank you @geomorillo https://github.com/geomorillo for coming in and
sharing your thoughts too.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-162607455
.

@woodsy1 if some of the people are so concerned about codeigniter and Yii, why aren't they at those websites. My concern is SMVC which I use in real live production sites. And yes I tend to get concerned  when some folks want to hack it up and bloat it up.
And if you read the comments carefully you will see that I gave a suggestion on how to work around a problem the individual is having, without changing the framework further.

@jimgwhit Thats fine but the manner in which you are talking to people here is not acceptable.

@woodsy1  I realize I can come across a little strong, but think about it someone is asking a question that they could do themselves with a little bit of ingenuity. I guess it bothers me when someone expects the framework to be  customized 500 different ways when that should be done by the user / programmer.

Again you have asked questions on this thread earlier before you had Dave helped you that I thought were simple but I did not have a go at you or your questions.
It is best unless you can help someone constructively and politely that you leave Dave to handle the questions.

@woodsy1 well I won't go on and on I promise, but let me leave it at this my question was on current usage in the actual current framework. Not a change that someone could customize them self as already clearly stated.  And yes I will leave it at that.

I have discovered a nice way of keeping your project completely self contained on local to allow you to put the entire thing in a git repo using virtual hosts. I will post a tutorial on it on the forums.

@woodsy1 oh nice I will keep an eye out for that.

I see @jimgwhit hate me? Sure?
I don't think my problem is multi customer in one system?
You build 2 system for 2 customer in 1 shared hosting?
I think you don't know what I say???
Stop disscuss about my problem.

Hello, some thoughts about SMVC restructuring.
First of all, I should say that I arrived to SMVC because because was choose by our team as a base framework to port a massive and complex e-Learning Portal, being monolithic/old-style, to HMVC (think something about 90MB source code), while maximizing the future application response speed, for supporting a maximum users on-line possible. Sure, SMVC being a  Micro-Framework, excelled in this field (4-6 times faster than the well acclaimed CodeIgniter, on the tests), and its (incipient) Modules support and namespaces was seen as advantages.
Before some to badmouth the Modules, I should say that using a Modular approach, hugely simplify the work in a team and permit to develop different combinations of facilities. Please remember that I look to SMVC as a base of a literally huge Portal, being developed by 10-12 programmers, and not as to develop some rather simple blog or presentation website...
Then, some critics and suggestions for SMVC 3.0.
First of all, namespace pollution and system/app isolation. I consider a wise decision to use name space 'App' for the application components, isolating them. Yet, we should remember that SMVC is not alone in the PHP (and Composer) Ecosystem. While, for a simple presentation site, using '\Core' and '\Helpers' will glorious works, to create some more complex site we will need to use another (Composer) packages. In other hand, in Composer World, anonymous (as in non-product) namespaces are considered being for local implementations.
So, my suggestion is to apply a name space also to 'system' path components. Us, we use a generic one: '\MVC', maybe Dave will choose a more proud one, i.e: '\Smvc', but in my opinion, the SMVC components should be enclosed in well defined namespaces. Is not complicated and simplify the life. Plus, think about the Proud Moment while reading:
class Controller extend \Smvc\Core\Controller
Secondly, no Events, and EventManager, at all? Come-on! An EventManager cam be written in two classes and around 100 lines of code, even if you do not want to reuse available components, i.e. from Symfony.
The Events are of fantastic utility, even for simple sites, if you don't want to write again and write again same code! Simple example: you have to develop two sites, but one should send an welcome mail, while another not, on user registration. Using Events, the only difference in code between those sites, is that in first one, a Mailer class watch the User Registration Events, and do its job.
In other hand, the Events are, well handily when you work with Modules. You can use them to extend the functionality of some Modules, using another Modules, etc.
Thirdly, right now, SMVC configuration is literally rudimentary. We have a class who do in its constructor some defines and initialization. That's all. Sure, for a simple blog maybe it is enough, but when complexity increase, the needed configuration elements increase too. Also, some Modules need specific configuration too.
One can argue that we can add all the "defines" in that today class. Well, it is a POV, but we miss right on the Modules idea: self-contained components. That's why I suggest that SMVC to do some real configuration, supporting Modules-side too. And it is not complicated. For example, we use:
namespace Core;

class Config {

    protected static $settings = array();

    public static function get($key) {
        return isset(self::$settings[$key]) ? self::$settings[$key] : null;
    }

    public static function set($key, $value) {
        self::$settings[$key] = $value;
    }

}

And, then, all is settled in some files in app/Config directory:
app/Config/bootstrap.php
app/Config/config.php
app/Config/constants.php
app/Config/routes.php
The file names I think that are self-explanatory. A very simple class like this one is very handily, because it permit even to have arrays as configuration parameters, instead of simple defines. In plus, there is a class called Modules, which walk on Config directories of every active module and load their configuration.
And talking about Configuration files, I believe that them should not stay in system/core, instead to have their dedicated directories. For example: 'app/Config', because they are specific to application.
Another argument is that in the SMVC's system directory shall be only the shipped SMVC product, which I touch only when I do an update because Dave do an update. All configuration, all logs, all customization should go on application directory, aka 'app'. Why?
Because in this way you can develop 1000 applications, every one different, with different databases, responding on different domains, while using ONE SMVC SYSTEM installation. And that's very handily for security updates. And yes, even in Shared Hosting this thing is possible, i.e. when using Hostgator.
Fourthly, I would like to argue about SMVC's Routing. Sure, is nice and fancy, but I consider very nice to have ability to easily extend the \Core\Router. For example, to support the Files Serving. What is file serving? Let's look at SMVC 3.0 tree. We see that (by default?) it use a public directory as webroot. A very security wise decision which I salute, but having the framework behind the webroot, we hit a problem: the Assets Files aren't available directly, being behind the Web accessible directories.
One can move those Asset Files on webroot. Yeah, can be a solution, but not most lucky one. You have to move the Asset Files, the Templates Asset Files, and what you do about Modules Asset Files? Move even them? But, like I said, the Modules shall be self-contained, right?
A much more simple solution for this problem is Asset Files Serving via Router. Using some preg_match, in URI dispatching, the Router can detect the Asset URIs and call a simple method which is a classic file downloader, rather that looking for matching Route. It is complicated? Nope. Look at this functional example:
    /**
     * Runs the callback for the given request.
     */
    public static function dispatch()
    {
        // Detect the URI and the HTTP Method.
        $uri = Url::detectUri();

        $method = Request::getMethod();

        // For properly Assets serving, the file URI should be as following:
        //
        // /templates/default/assets/css/style.css
        // /modules/blog/assets/css/style.css
        // /assets/css/style.css

        if (Request::isGet()) {
            if(preg_match('#^assets/(.*)$#i', $uri, $matches)) {
                // In protected Assets path.
                $filePath = 'assets/'.$matches[1];

                self::serveAsset($filePath);

                return;
            }
            else if (preg_match('#^(templates|modules)/(.+)/assets/(.*)$#i', $uri, $matches)) {
                // We need to classify the second match string (the Module/Template name).
                $moduleName = Inflector::classify($matches[2]);

                $filePath = $matches[1].'/'.$moduleName.'/Assets/'.$matches[3];

                self::serveAsset($filePath);

                return;
            }
        }

        // Routes the current request.

        foreach (self::$routes as $route) {
            if ($route->match($uri, $method)) {
                // Found a valid Route; invoke the Route's Callback and go out.
                self::invokeObject($route->callback(), $route->params());

                return;
            }
        }

        // No valid Route found; invoke the Error Callback with the current URI as parameter.
        $params = array(
            htmlspecialchars($uri, ENT_COMPAT, 'ISO-8859-1', true)
        );

        self::invokeObject(self::$errorCallback, $params);
    }

Sure, you will notice that we use a "custom" class, called Route and to note that auto-dispatching is not gone (its work is done in Route). Yep, we do it to simplify the code, and we do not do huge complications compared with the orthodox SMVC. As idea, the Files Serving is in the first part of this method.
That File Serving even permit to condition the files access on different situations (user logged in, time limit or traffic limit, etc).
Lastly, I consider that will be very nice if SMVC do something about the salad of capitalized and lowercase directories. Sure, some needs to be capitalized because composer walk on them. But, why not use all directories capitalized? We have advantages to use views instead of Views? Nope. I for one I believe that using, like I said, the all Capitalized Directories structure give a consistent look, and even simplify the developers life.
Finally, hopping that my critics and suggestions are somewhat useful, a sincere
All the Best!

@LuckyCyborg thank you so so so so so much, you just made my main point convincing that someone could take the framework as is and custom modify it to suit their needs. So let's not flim flam up the framework but let people do what you have done download it and custom modify it to suit your particular needs. @daveismyname , like I have mentioned this framework is supposed to be a smaller to medium scale simple framework if someone wants all the big humongous giant features why don't they use laravel or send?
But someone who is advanced could take the framework as downloaded and modify it to suit their sites needs, they could even scale it for a heavy duty website if need be.  If advanced enough someone could even write their own router.

@LuckyCyborg  I'm feeling excited about your project. Can you share your core project code?
Thanks you!

And to try to put this in a nice way let's say,
Joe wants feature A

Billy Bob wants feature B

Cindy wants feature C

Couldn't they install the framework, and custom write their own classes and customize in those features they want themselves? Billy Bob might not want what Cindy needs, Joe Blow may not need what Rodriguez needs, Sue Bob may not need any of it. So hopefully this explains, it is a framework that a person can customize themselves to suit their own needs without putting junk in there that someone else does not need or want.

I really want to demonstrate the Service layer that I mentioned earlier (pretty far scroll distance actually :chicken:)
Demo on Service Layer
To demonstrate how easy it is to not use SQL anymore for the most basic CRUD operations, and even not write it for models too I made a branch on my fork:
https://github.com/tomvlk/php-framework/tree/demo-service-layer
You can clone and run it (note: it's on 3.0). Database export is also included!
How?
In the Demo controller you can see the logic of getting something from the database. Just basicly doing this will get you the car with id 1:
$carService = new \App\Services\CarService();
$car = $carService->get(1);

And because the car has a relation to the 'Make' model you can map the relation with a lazy getter inside of the model Make:
Source of the lazy getter inside of car to get the make object that is coupled with the car:
public function getMake() {
    // Will check if make is already 'cached' in this model. If not, then fetch it!
    if ($this->make == null) {
        // Fetch Make object
        $service = new MakeService();
        $this->make = $service->get($this->makeid);
    }

    // Return the make object
    return $this->make;
}

With this lazy getter you can call the getMake() at any time on your returned Car model from the database. This will only get the make that has a relationship from car when you call getMake() for the first time. When using the getMake() after the first time it will use cached make that is declared in the model Car.
$carService = new \App\Services\CarService();
$car = $carService->get(1);

$make = $car->getMake();

Why
Better maintainability, less SQL inside of your model, because model should be only data in my opinion, and no database getters (that is actually the service layer in the current 2.* version).
Hard to explain it without showing you the whole code So please take a look at the source here: https://github.com/tomvlk/php-framework/tree/demo-service-layer

@tomvlk you further emphasize my point that someone could take the framework as is and modify it to suit their own needs, how come some people just don't understand that. And again trying to be nice here I disagree, the model is where the database logic goes. @daveismyname  done this correctly. And @daveismyname has said you can use another database provider such as eloquent if you choose. And unless you're changing data getters and setters are unnecessary, and again if you need a getter settter class simply write one.

@jimgwhit take it easy
I just explained my idea. It seems you feel attacked once I explain it.
And didn't say anything about doing something wrong here. It's how you are building the system.
It's more like, look this could be a great style on how to create big applications when using much db logic and you want to seperate it from the objects that it will be mapped in.
And someone asked how that would look like, so please take it easy!

@LuckyCyborg thanks for this I'm going to read through this again so I understand your points before commenting on them.
@tomvlk thank you I did ask you about this I'll have a look at your repo.
@jimgwhit everyone know you're reluctant to change and if you had your way the framework would never change in any way, you've made your views extremely clear please give others the chance to do the same, commenting as you do may put other people off from expressing their ideas.
At this point I'm not ruling anything out let's get the ideas out there see what's useful and what's not

Yes @jimgwhit take it easy he is just proposing some ideas, i think they are interesting , also remember that every software has to evolve at some point, or should we stay only with the 2.x branch forever?.

@geomorillo and @daveismyname it was mentioned above,
you can always fork your own copy and do your own version, i have one myself, with my own modifications and they work really great.
Ok that is all I am trying to say if I can fork my own why can't they fork their own and modify as need be.
I have no problem with people suggesting things, but some are wanting to add things that is only highly specialized to meet their needs only, which should be a customized thing and not a cast in stone thing.

@jimgwhit Service layer isn't specialized, it's a well known implementation.

@tomvlk would it be required to use the service layer?  Could I still use things the regular way even if the framework had the service layer included?

but every time someone comments you come along and comment to say they should not be doing that, it's going to lead to less confident people to not comment at all.
Some suggestions are for things I'm not aware off lets take advantage of each other's knowledge we as individuals don't know everything.
If things can be useful for wide audiences then that's got to be a good things, by looking at the services for instance that add functionality but does not take away the current style of writing code it's a choice to use it or not.

@daveismyname I have absolutely no problem with the additions if like you said they are optional.

I think they are optional @jimgwhit, or i would prefer them to be optional, but they are really interesting worth looking at.

it's worth looking at the options then looking at implementations they don't necessarily end up in the framework but lets not limit ourselves right away

@tomvlk Thanks for sharing your code in regards to the service layer, I was quite interested in how it would have worked. :smile:

@jimgwhit Thanks for your kind words, but when someone completely re-implement the Router, Controller, View and Language (with some INTL/ICU taste!) classes, introducing Themes as in Layouts and Fragments, unique language files support for System, App, Modules and Templates, change the configuration mode using a new class (Config) as base, the framework structure and initialization (like described with bootstrap, config, constants & Co.), when even its namespaces are changed, that can be barely called... customization.
Instead, I believe that is it called eventually fork, even if it is not public, yet. Practically, I can say that The Thing what we developed and use is a different animal, which is and behave different to SMVC. The main problem is that we have no intention to fork SMVC; that's WHY we try to contribute back some of our modifications and enhancements, hopping that using common sense and small changes, SMVC, in a future version, maybe can accommodate our requirements, without us to rewrite its Core Components.
Yet, you should do not worry, we have no intention to ask Dave to write the Second Laravel, CakePHP  or CodeIgniter, being more than happy to use the original things when is the case, still having a project with specific requirements, which ask us to use SVMC for implementation. And, I for one, I believe that simple is not another word for rudimentary, instead we all can have a simple and smart framework. Our suggestions aren't of nature to make SMVC fat or complicated, take them as small (and maybe smart) enhancements.
@nhymxu Well, like I said, we have no intention to fork SMVC, but, in future, if there is enough interest, there will be no problem to publish the Project's Core as an add-on on top of SVMC. My colleagues look even with enthusiasm to this idea and they say to be willing to follow the Core Framework with a companion application, a simple but complete CMS, to demonstrate how the things works. Yet, like I described in this post, do not expect to feel SMVC working on top of our solution. Maybe some taste of CakePHP.
Yet, I say again, we have no intention to fork SVMC and our Core Framework will be published only as solution on top of SVMC, no another way.
@daveismyname I wait your comments and questions.

I actually have one project I did in laravel and even there on their forums sometimes they talk about repository patterns and services. However you can completely use laravel without having a repository pattern or a service, if you don't believe me download and install laravel 5.1 you can completely database operations just using the querybuilder with no specialized services or repository patterns they are completely optional.
I don't think that is too much to ask.

@jimgwhit At a frugal look on those Services, no one force you to use them. If you like the ol'good Database/Model style, those classes are always there for you, nothing is changed.

OK, then my suggestion to enhance the Routing in the SVMC 3.0; offering a better support to further enhance the Router, if is the case.
Additional method on \Helpers\Request
    /**
     * Gets the request method.
     *
     * @return string
     */
    public static function getMethod() {
        $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';

        if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
            $method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];
        }
        elseif (isset($_REQUEST['_method'])) {
            $method = $_REQUEST['_method'];
        }

        return strtoupper($method);
    }

Additional method to \Helpers\Url
    public static function detectUri()
    {
        $requestUri = $_SERVER['REQUEST_URI'];
        $scriptName = $_SERVER['SCRIPT_NAME'];

        $pathName = dirname($scriptName);

        if (strpos($requestUri, $scriptName) === 0) {
            $requestUri = substr($requestUri, strlen($scriptName));
        }
        else if (strpos($requestUri, $pathName) === 0) {
            $requestUri = substr($requestUri, strlen($pathName));
        }

        if (($requestUri == '/') || empty($requestUri)) {
            return '/';
        }

        $uri = parse_url($requestUri, PHP_URL_PATH);

        return str_replace(array('//', '../'), '/', ltrim($uri, '/'));
    }

An new class, called \Core\Route
namespace Core;

/**
 * The Route class is responsible for routing an HTTP request to an assigned callback function.
 * The Router tries to match the requested URL against a series of URL patterns.
 */
class Route
{
    /**
     * @var string HTTP method or 'ANY'
     */
    private $method;

    /**
     * @var string URL pattern
     */
    private $pattern;

    /**
     * @var mixed Callback
     */
    private $callback = null;

    /**
     * @var array Route parameters
     */
    private $params = array();

    /**
     * @var string Matching regular expression
     */
    private $regex;

    /**
     * Constructor.
     *
     * @param string $method HTTP method
     * @param string $pattern URL pattern
     * @param mixed $callback Callback function
     */
    public function __construct($method, $pattern, $callback)
    {
        $this->method   = $method;
        $this->pattern  = $pattern;
        $this->callback = $callback;
    }

    public function match($uri, $method)
    {
        if (($this->method != $method) && ($this->method != 'ANY')) {
            return false;
        }

        if ($this->matchUri($uri)) {
            return true;
        }

        return false;
    }

    /**
     * Checks if a URL matches the Route pattern.
     *
     * @param string $uri Requested URL
     * @return boolean Match status
     */
    public function matchUri($uri)
    {
        // Wildcard or exact match.
        if (($this->pattern === '*') || ($this->pattern === $uri)) {
            return true;
        }

        $last_char = substr($this->pattern, -1);

        // Build the regex for matching.
        if (strpos($this->pattern, ':') !== false) {
            $regex = str_replace(
                array(':any', ':num', ':all', ':hex', ':uuidV4'),
                array('[^/]+', '-?[0-9]+', '.*', '[[:xdigit:]]+', '\w{8}-\w{4}-\w{4}-\w{4}-\w{12}'),
                $this->pattern
            );
        }
        else {
            $regex = $this->pattern;
        }

        $regex = str_replace(array('(/', ')', '/*'), array('(?:/', ')?', '(/?|/.*?)'), $regex);

        // Fix trailing slash.
        if ($last_char === '/') {
            $regex .= '?';
        }
        // Allow trailing slash.
        else {
            $regex .= '/?';
        }

        // Attempt to match the Route and extract the parameters.
        if (preg_match('#^' .$regex .'(?:\?.*)?$#i', $uri, $matches)) {
            // Remove $matched[0] as [1] is the first parameter.
            array_shift($matches);
            // Store the extracted parameters.
            $this->params = $matches;
            // Also, store the compiled regex.
            $this->regex = $regex;

            return true;
        }

        return false;
    }

    //
    // Some Getters

    public function callback()
    {
        return $this->callback;
    }

    public function params()
    {
        return $this->params;
    }

    public function regex()
    {
        return $this->regex;
    }

}

The rewriten class on \Core\Router
namespace Core;

use Core\Config;
use Core\Route;
use Helpers\Request;
use Helpers\Url;

/**
 * Router class will load requested controller / closure based on url.
 */
class Router
{
    private static $instance;

    /**
     * Array of routes
     *
     * @var array $routes
     */
    private $routes = array();

    /**
     * Set an Error Callback
     *
     * @var null $errorCallback
     */
    private $errorCallback = '\Core\Error@index';

    // Constructor
    public function __construct()
    {
        self::$instance =& $this;
    }

    public static function &getInstance()
    {
        if(! self::$instance) {
            $appRouter = APPROUTER;

            self::$instance = new $appRouter();
        }

        return self::$instance;
    }

    /**
     * Defines a route with or without Callback and Method.
     *
     * @param string $method
     * @param array @params
     */
    public static function __callStatic($method, $params)
    {
        $router = self::getInstance();

        $router->addRoute($method, $params[0], $params[1]);
    }

    /**
     * Defines callback if route is not found.
     *
     * @param string $callback
     */
    public static function error($callback)
    {
        $router = self::getInstance();

        $router->callback($callback);
    }

    public function callback($callback = null)
    {
        if(is_null($callback)) {
            return $this->errorCallback;
        }

        $this->errorCallback = $callback;
    }

    /**
     * Maps a Method and URL pattern to a Callback.
     *
     * @param string $method HTTP metod to match
     * @param string $pattern URL pattern to match
     * @param callback $callback Callback object
     */
    public function addRoute($method, $route, $callback)
    {
        $method = strtoupper($method);
        $pattern = ltrim($route, '/');

        $route = new Route($method, $pattern, $callback);

        array_push($this->routes, $route);
    }

    /**
     * Invoke the callback with its associated parameters.
     *
     * @param  object $callback
     * @param  array  $params array of matched parameters
     * @param  string $message
     */
    protected function invokeObject($callback, $params = array())
    {
        if (is_object($callback)) {
            // Call the Closure.
            return call_user_func_array($callback, $params);
        }

        // Call the object Controller and its Method.
        $segments = explode('@', $callback);

        $controller = $segments[0];
        $method     = $segments[1];

        // Initialize the Controller
        $controller = new $controller();

        // Execute the Controller's Method with the given arguments.
        return call_user_func_array(array($controller, $method), $params);
    }

    public function dispatch()
    {
        // Detect the URI and the HTTP Method.
        $uri = Url::detectUri();

        $method = Request::getMethod();

        foreach ($this->routes as $route) {
            if ($route->match($uri, $method)) {
                // Found a valid Route; invoke the Route's Callback and go out.
                $this->invokeObject($route->callback(), $route->params());

                return true;
            }
        }

        // No valid Route found; invoke the Error Callback with the current URI as parameter.
        $params = array(
            htmlspecialchars($uri, ENT_COMPAT, 'ISO-8859-1', true)
        );

        $this->invokeObject($this->callback(), $params);

        return false;
    }

}

The new \Core\Router class is compatible as configuration with the old class, offering also the ability to use optional parameters in patterns, then will work a pattern something like:
blog/archive(/:num(/:num(/:num)))
This example pattern will match the URIs:
/blog/archive/2015/12/31
/blog/archive/2015/12
/blog/archive/2015
/blog/archive

To note that for a properly work, this new Router need a define in Config class,
/**
 * Set the Application Router.
 */
define('APPROUTER', '\Core\Router');

and a slightly different approach in /public/index.php
// We should get the Router instance before to start Routes configuration.
$router = Router::getInstance();

// Load the Routes
include SYSTEM .'Core/routes.php';

// Execute matched routes
$router->dispatch();

Also, there is no fallback switch and no autoDispatch.
You'll notice that the new \Core\Router is very different from the orthodox one, and use only few static functions. But the best of the bests is that class can be easily extended; for example, if we want a Classic Router, running in ol'good style of AutoDispatching or like the CodeIgniter routes, there we go:
namespace Core;

use Core\Config;
use Core\Route;
use Helpers\Request;
use Helpers\Url;

/**
 * ClassicRouter class will load requested controller / closure based on url.
 */
class ClassicRouter extends \Core\Router
{
    // Constructor
    public function __construct()
    {
        parent::__construct();
    }

   /**
     * Ability to call controllers in their module/directory/controller/method/param way.
     */
    public static function autoDispatch($uri)
    {
        // NOTE: This Auto-Dispatch routing use the styles:
        //
        // <DIR><directory><controller><method><params>
        // <DIR><module><directory><controller><method><params>

        $parts = explode('/', $uri);

        // Loop through URI parts, checking for the Controller file including its path.
        $controller = array_shift($parts);

        // Classify, to permit: '<DIR>/modules/admin/file_manager/' -> '<SMVC>/app/Modules/Admin/FileManager/
        $controller = str_replace(array('-', '_'), '', ucwords($controller, '-_'));

        // The base variables
        $basePath = 'Controllers/';

        // Verify if the first URI part match a Module.
        $moduleName = $controller;

        $testPath = SMVC.'app/Modules/'.$moduleName;

        if(is_dir($testPath)) {
            // Walking in a Module path.
            $basePath = 'Modules/'.$moduleName.'/Controllers/';

            // Go further only if have other URI Parts, to permit URL mappings like:
            // '<DIR>/clients' -> '<SMVC>/app/Modules/Clients/Controllers/Clients.php'
            if(! empty($parts)) {
                $controller = array_shift($parts);
                $controller = str_replace(array('-', '_'), '', ucwords($controller, '-_'));
            }
        }
        else {
            $moduleName = '';
        }

        // Check for the Controller, even in sub-directories.
        $directory = '';

        while (! empty($parts)) {
            $testPath = SMVC.'app/'.$basePath.$directory.$controller;

            if (! is_readable($testPath .'.php') && is_dir($testPath)) {
                $directory .= $controller .'/';

                //
                $controller = array_shift($parts);
                $controller = str_replace(array('-', '_'), '', ucwords($controller, '-_'));

                continue;
            }

            break;
        }

        // Get the normalized Controller
        $defaultOne = !empty($moduleName) ? $moduleName : DEFAULT_CONTROLLER;
        $controller = !empty($controller) ? $controller : $defaultOne;

        // Get the normalized Method
        $method = !empty($parts) ? array_shift($parts) : DEFAULT_METHOD;

        // Get the Controller's className.
        $controller = str_replace('/', '\\', $basePath.$directory.$controller);

        // Controller's Methods starting with '_' are not allowed also to be called on Router.
        if(($method[0] === '_') || !class_exists($controller)) {
            return false;
        }

        // Initialize the Controller
        $controller = new $controller();

        // Check for a valid public Controller's Method.
        if(! in_array(strtolower($method), array_map('strtolower', get_class_methods($controller)))) {
            return false;
        }

        // Execute the current Controller's Method with the given arguments.
        call_user_func_array(array($controller, $method), !empty($parts) ? $parts : array());

        return true;
    }

    public function dispatch()
    {
        // Detect the URI and the HTTP Method.
        $uri = Url::detectUri();

        $method = Request::getMethod();

        foreach ($this->routes as $route) {
            if ($route->match($uri, $method)) {
                // Found a valid Route; invoke the autoDispatch and go out.
                $callback = $route->callback();

                if(! is_object($callback)) {
                    $autoUri = preg_replace('#^' .$route->regex() .'$#', $callback, $uri);

                    $this->autoDispatch($autoUri);
                }
                else {
                    call_user_func_array($callback, $route->params());
                }

                return true;
            }
        }

        // No valid Route found; invoke the Error Callback with the current URI as parameter.
        $params = array(
            htmlspecialchars($uri, ENT_COMPAT, 'ISO-8859-1', true)
        );

        $this->invokeObject($this->callback(), $params);

        return false;
    }

}

To activate the ClassicRouter we need to setup:
/**
 * Set the Application Router.
 */
define('APPROUTER', '\Core\ClassicRouter');

To note that new ClassicRouter have much greater performance compared with the orthodox autoDispatcher method of the actual \Core\Router, supporting patterns, just like the base \Core\Router, and supporting also, very important, the sub-directories on App and Modules. Then, you can happily use, for example, for your controllers paths, the styles:
/app/Controllers/Admin/Blog.php
/app/Modules/User/Controllers/Admin/Users.php

And, yeah, if the SVMC 3.0 is driven by this enhanced Router, not only you have, native, a better Router, but us we can easily extend it to support our Asset Serving style and other things, without to completely replace the main thing.
Finally, I will ask if there is interest for a simple but very powerful \Core\Language class replacement, which support the PHP's 5.5.x native INTL based on ICU, with support for single language file per App and Module or Template, loading multiple language domains, etc. It needs the Config class mentioned in my previous (long) post, some functions to be defined in index.php or a configuration file, but the result is somewhat similar with what can be seen in CakePHP 3.0
Example of usage:
Session::set('message', array('type' => 'success', 'text' => __d('user', 'User <b>{0}</b> was Added', $userinfo['username'])));

Notice the function called __d(), that's command read the language file from the domain (of Module) User and translate the message with support for parameters.
BTW, our Language class have as companion a (Linux) script able to scan the PHP files from framework, to extract the translatable strings and to update the language files on App and Modules.
All the best!

@LuckyCyborg does the router you show handle a regular querystring like
Site/dogs?page=4&search=b

Or will I be forced into
Site/dogs/4/b

I don't like friendly url's I prefer querystring.

I would like to comment but got nothing to say, this is going way too far ahead of me. (Not that I tried v3 yet)

@LuckyCyborg I really like your routing methods, more object oriented. But will it affect the performance? (Not always important btw, maintainability is more important in my opinion. but just curious).

@jimgwhit If you talk about my proposed Router ability to work without Apache's ModRewrite support, then yes, it can works fine without it, using URLs similar with those accepted by CodeIgniter. For example, the following URLs are working by default:
http://www.mywebsite.org/admin/users/edit/3

http://www.mywebsite.org/index.php/admin/users/edit/3

The second URL do not need the Apache's ModRewrite to be active. In other hand, my proposed Router, and, very important, even the SVMC's Macaw based Router, both do not handle the QUERY_STRING on URIs processing. Even some Big Houses do not do, i.e. CodeIgniter.
Stil, if the passed URI contains a QUERY_STRING, i.e. 'admin/users/list?page=4&search=jim', our Router (to be more precise, on Route::matchUri) automatically capture the query part, if exists, as the last parameter. So, if you have the Admin/Users Controller's method something like:
public function list($query = '')
{
...
}

On the method, the $query parameter will contains page=4&search=jim . One can explode this string, then map the parts as an array keys/values, eventually applying some XSS protection. Finally, guess what? You will obtain something similar with what already exists in $_GET.
So, assuming that you manually handle the QUERY parameters in your Controllers, will work by default the URL's like:
http://www.mywebsite.org/admin/users/list?page=4&search=jim

http://www.mywebsite.org/index.php/admin/users/list?page=4&search=jim

And, if we talk about Laravel, it's Routing complexity is about several magnitudes greater than the proposed code, so is absolutely normal to not have all Laravel's Routing abilities.
But, you know what is the best part, if Dave accept our Router? If you can't live without handling the QUERY_STRING via Routing, you can easily extend the (base) \Core\Router and to create and use one which automatically handle those things.
Again, we propose a simple, yet improved Routing, which can be easily extended to support new facilities, not the final Routing which we use on the e-Learning Portal, which is much more complex, especially on Files handling.
I.e. our production Router can and condition the User access to some files by: the User is logged in, the User taken a specified Course, he is in a 3 hours time limit, and have given access for the current IP only.
To respond to your last question, there is no public repository for our code. In fact, the Portal for what we have interest on SVMC, is written on request for the final owner, and it will not be published as source code and/or for downloading, and the SMVC license permit well that way. Yet, eventually we muse about publishing the Core Framework as add-on on top of SMVC, but this is another story.
Also, I'm there as job task, being instructed to contact the SVMC community and to start the communication, eventually, to propose diverse enhancements.
@tomvlk As performance, compared with the SVMC's orthodox Router, our own the tests says that our Routing is similar as speed, behaving slightly better in some situations. For example, to support something equivalent with a Route with optional parameters, like:
blog/archive(/:num(/:num(/:num)))
using the actual Routing, you need to define Four Routes, and the Router will loop over them. Our Router will got it on first shot.

@LuckyCyborg Thanks for the fast reply on the performance. And indeed you don't need multiple route definitions if you have optional paramters. This will reduce the number of routes defined and will reduce time to do the for loop.
I really think that this will improve the router and should be in the new version, as the current router lacks on some features you have implemented.

@BryanYeh in case you didn't see it, @daveismyname did a video on this:
http://simplemvcframework.com/screencasts/v2.1/build-a-login-authentication-system
Also an example I do is I made an admin controller and I
$username = $_POST['username'];
            $password = $_POST['password'];
            $darray = $this->Admin->getHash($username);

In model
public function getHash($username)
    {
        $data = $this->db->select("SELECT ownerid, password FROM " . PREFIX . "users WHERE
        username = :username", array(':username' => $username));
        return $data;
   }

and back in controller
if(password_verify($password, $darray[0]->password) == false){
              die('wrong username or password');  //put a redirect here
            } else {
                Session::set('loggin', true);
                Session::set('owner', $darray[0]->ownerid);
               Url::redirect('pet');
            }

In users table you could add fields for roles, sub roles, etc
For user to see there own data only:
public function getPets($offset = "", $rowsperpage = "", $petsearch = "")
    {
        $pagingQuery = "LIMIT {$offset}, {$rowsperpage}";
        $petsearch = $petsearch . "%";
       if (Session::get('owner') == '1') {
            return $this->db->select("SELECT * FROM " . PREFIX . "pets WHERE petname like :search ORDER BY petname " . $pagingQuery, array('search' => $petsearch));
        } else {
            return $this->db->select("SELECT * FROM " . PREFIX . "pets WHERE petname like :search AND ownerid = ownerid ORDER BY petname " . $pagingQuery, array('search' => $petsearch, 'ownerid' => Session::get('owner')));
        }

There  are several ways to implement it.

@LuckyCyborg you mentioned exploding and mapping a querystring.  In Laravel I don't have to explode and map nothing,  I can have a route like
Route::get('pets', ['middleware' => 'auth', 'uses' => 'PetsController@petlist']);

pass a querystring the regular way and in controller
if (isset($_REQUEST['search'])) {
            $t1 = $_REQUEST['search'];
        } else {
            $t1 = "";
        }

Notice I am getting the querystring the normal way.  I am not having to
public function petlist()  // nothing has to be passed in the parenthesis since regular querystring.
    {
      // more code
   }

If the router has to change and can't use querystring like it does now, then I plead with @daveismyname let's use the routing system Laravel is using. I don't want to have to explode and map or do some special thing with a querystring.  I want the querystring to work as always.
If this querystring thing is going to be an issue, someone let me know right now.  I have real production sites, I use querystring, and  that's that.  I need to know how to proceed.

@jimgwhit Long story short, both Routing systems, the actual one and the one proposed by us, literally do not manage, change or modify the QUERY_STRING elements, which you can access via as always, via $_REQUEST and $_GET. Nothing is changed or will be changed, if you massive use in your applications via PHP's default ways. OKay?
In other hand, our Routing do not have the complexity of the Laravel Routing and do not want to be a Routing similar with the Laravel ones. It is just a enhanced version of the existent one, even compatible as routes configuration, nothing more.
Also, if your typical routing looks like:
Route::get('pets', ['middleware' => 'auth', 'uses' => 'PetsController@petlist']);

permit me to ask, on which framework are written your applications? SVMC or Laravel?

@LuckyCyborg I have one using laravel, others are SMVC.  Please explain in greater detail what you meant about having to explode and map the querystring, please.

@jimgwhit Nothing more than that our Routing have also the ability to parse the URI and to offer the non-processed QUERY_STRING part as last parameter to a Controller Method. That's all.
BUT, YOU DO NOT NEED to do something with this supplementary parameter, even you can ignore it. You can just use as always your $_REQUEST and $_GET friends, which are untouched, and let's be happy. :)

IN smvc I have
Router::any('pet/index', 'Controllers\Pet@index');

after a successful edit I can pass a regular querystring  in url
Url::redirect('pet?p=' . Session::get('petpage') . '&search=' . Session::get('petsearch'));

which would look like
site/pet?p=2&search=ro  //just example here

I don't use what's call friendly URL's so I dont mess with route filters.

    (:any) any - can use characters or numbers
    (:num) num - can only use numbers
    (:all) all - will accept everything including any slash paths

I pass data with the regular querystring in the url.
When passing data with  a querystring, you don't need or use route filters.
the regular route such as
Router::any('pet', 'Controllers\Pet@index');

will work.
And of course in the controller you can use
$_GET or $_REQUEST or the helper class like
$t1 = Request::get('search');  //using request helper

But I do not have to do a special thing to explode and map nothing.

@jimgwhit Everything which you describe is not changed a bit using rather the today SMVC Routing, even you have to use the proposed one, which is punctually compatible with the existent one as Routes configuration. Again, bbsolutely nothing will be changed from your POV.

@LuckyCyborg you said non-processed QUERY_STRING part as last parameter to a Controlle Method
Show an example route ofhow this would work please and possible the top part of controller where you are getting the data.  for an example can we say that we are passing:
site/pet?p=2&search=b&color=black

Please give example.

@jimgwhit If you want to see, what you have additionally, if you use our Routing, please give me the actually SVMC Route which you use to map this URI, and your complete Controller method to process it.
In other hand, for those who want to test the performance or even the introduced abilities of our Routing, I prepared a repository and a branch.
https://github.com/LuckyCyborg/simple-mvc-framework/tree/3.0-improved-routing

My routes for this
Router::any('pet', 'Controllers\Pet@index');
Router::any('pet/index', 'Controllers\Pet@index');
Router::any('pet/add', 'Controllers\Pet@add');
Router::any('pet/edit', 'Controllers\Pet@edit');

controller // not cleaned up, this is test data
public function index()
    {
        echo 'made it here';
        Session::set('owner', '1');
        echo Session::get('owner');
        //$this->_pet = new Models\pet_model();
        //$this->_contacts = new \Models\contacts();
        //Session::set('petsearch','b');
        //echo "ps".Session::get('petsearch');
        $petsearch = (isset($_REQUEST['psch']) <> '' ? $_REQUEST['psch'] : "");
        //echo "ps".Session::get('petsearch');
        Session::set('petsearch', $petsearch);
        //$_SESSION['petsearch'] = "b";
        //$_SESSION['petsearch'] = $petsearch;
        //$pm = new \Models\PetModel();
        $petrows = $this->Pet->petCount($petsearch);
        echo "pr" . $petrows . "pr";
        print_r($this->Pet->petCount($petsearch));
        //$_SESSION['petrows'] = $petrows;
        Session::set('petrows', $petrows);
        $pages = new HelpersPaginator('5', 'p');
        //$pages = new \helpers\paginator('5','');
        //$_SESSION['petpage'] = $pages->get_instance();
        Session::set('petpage', $pages->getInstance());

        $pages->setTotal($petrows);
        //$data['page_links'] = $pages->page_links();
        $data['pageLinks'] = $pages->pageLinks('?', '&psch=' . $petsearch);
        $data['title'] = 'pet';
        $data['pets'] = $this->Pet->getPets($pages->getLimit2(), $pages->getPerpage(), $petsearch);
        //good $data['pets'] = $this->_pet->get_pets($pages->get_limit(), $petsearch);
        $this->view->renderTemplate('header', $data);
        $this->view->render('pet/index', $data);
        $this->view->renderTemplate('footer', $data);
    }

I added the &color=black to see what an extra querystring parameter would do.

@LuckyCyborg I just wanted to see how a route in your routes would change for this
site/pet?p=2&search=b&color=black

Surley you can show example and using the requesrt helper to
retrieve the data please.

@jimgwhit Sorry for delayed response, but I haven some things to do.
So, there is NO CHANGE in your Routes. Your Controller's Method will work with no problem.
Looks like you use:
Router::any('pet', 'Controllers\Pet@index');
Router::any('pet/index', 'Controllers\Pet@index');
Router::any('pet/add', 'Controllers\Pet@add');
Router::any('pet/edit', 'Controllers\Pet@edit');

Those Routes are perfectly compatible with the proposed Router. NOTHING to change in your part. Eventually, if you talk about SMVC 3.0, because @daveismyname decided this way, you should modify the Controllers namespace. Something like:
Router::any('pet', 'App\Controllers\Pet@index');
Router::any('pet/index', 'App\Controllers\Pet@index');
Router::any('pet/add', 'App\Controllers\Pet@add');
Router::any('pet/edit', 'App\Controllers\Pet@edit');

Note that this change is required your Routing to work on the default SMVC 3.0, not by our Routing.
Like I said, this Route compatibility is obtained by Design.
Still, the QUERY part to arrive on Routing, you should modify on \Helpers\Url:
    public static function detectUri()
    {
        $requestUri = $_SERVER['REQUEST_URI'];
        $scriptName = $_SERVER['SCRIPT_NAME'];

        $pathName = dirname($scriptName);

        if (strpos($requestUri, $scriptName) === 0) {
            $requestUri = substr($requestUri, strlen($scriptName));
        }
        else if (strpos($requestUri, $pathName) === 0) {
            $requestUri = substr($requestUri, strlen($pathName));
        }

        if (($requestUri == '/') || empty($requestUri)) {
            return '/';
        }

        $uri = parse_url($requestUri, PHP_URL_PATH);

        return str_replace(array('//', '../'), '/', ltrim($uri, '/'));
    }

AS:
    public static function detectUri()
    {
        $requestUri = $_SERVER['REQUEST_URI'];
        $scriptName = $_SERVER['SCRIPT_NAME'];

        $pathName = dirname($scriptName);

        if (strpos($requestUri, $scriptName) === 0) {
            $requestUri = substr($requestUri, strlen($scriptName));
        }
        else if (strpos($requestUri, $pathName) === 0) {
            $requestUri = substr($requestUri, strlen($pathName));
        }

        if (($requestUri == '/') || empty($requestUri)) {
            return '/';
        }

        return str_replace(array('//', '../'), '/', ltrim($requestUri, '/'));
    }

Note that I have eliminated the parse_url() at the end of method. After those modifications, is supposed to have a copy of the current query_string as last parameter for method. For example, if you change:
public function index($str = '')

when using the base Core\Router, not the ClassicRouter, the $str variable should contains p=2&search=b&color=black.
NOTE that this is an additional feature, used by us on some extensions of this (proposed) Routing, then you can completely ignore this ability and use the normal style, as always.

@LuckyCyborg I don't understand
public function index($str = '')

And you didn't show how to use the request
helper  to get the two values
p=2&search=b&color=black

Search and color.  The p is pagination.  In controller would I still

$t1 = Request::get('search');

$mycolor = Request::get('color');

If this isn't correct, what is the way using your proposal?
Example please of retrieving this in a controller.
And how is p passed to paginate?
And why would I need
($str = '')

Currently in Laravel nothing extra is needed in the controller method for a querystring to work.
Still looks like
public function index()

So why in yours do we need str=''.
As stated if @daveismyname is going to drastically change routing, why not
Just use the one Laravel is using so no special technique has to be accomplished to get a querystring passed.

@jimgwhit Literally, like I said, you should ignore this feature of passing the raw query as last parameter to a Controller Method, if you have no intention to extend the Routing in special ways, or to do special processing in your Controllers.
To note also that this thing is disabled/ignored by default by Url::detectUri() and there are no difference of behaviour on QUERY processing, compared to actual Router. Read: the QUERY_STRING is ignored and you should retrieve the query_string by standard methods.

@jimgwhit perhaps you should take this off the thread with @luckycyborg
Your questions aren't making sense he has answered you a number of times
and you have just clogging the thread with the same question over and over
On Dec 12, 2015 6:25 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

@LuckyCyborg https://github.com/LuckyCyborg I don't understand
public function index($str = '')
And you didn't show how to use the request
helper to get the two values
p=2&search=b&color=black
Search and color. The p is pagination. In controller would I still
$t1 = Request::get('search');
$mycolor = Request::get('color');
If this isn't correct, what is the way using your proposal?
Example please of retrieving this in a controller.
And how is p passed to paginate?
And why would I need
($str = '')
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164025930
.

He still hasn't show controller example.

Get his email talk with him directly.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164030057
.

@woodsy1 having to put str='' is not the same, and frankly I don't care if that's no big deal to you but it is a real big deal to me yes it is. Remember I also have a right to voice my opinion I'd rather have the Laravel router. Now that's my honest to goodness opinion if you want something else that is your opinion which you are entitled to. But until he shows the controller example like I asked the complete question has not been answered.

Maybe a good idea to create a seperate issue for the discussions for the different components in 3.0. Because this isn't anymore about the folder restructure but more like feature requests etc.
Btw, @jimgwhit you said before: "Couldn't they install the framework, and custom write their own classes and customize in those features they want themselves?" :hushed: . Already regret saying it? Lol.

He has answered you a number of times!!!!!
This answers your question
"public function index($str = '')
when using the base Core\Router, not the ClassicRouter, the $str variable
should contains p=2&search=b&color=black.
NOTE that this is an additional feature, used by us on some extensions of
this (proposed) Routing, then you can completely ignore this ability and
use the normal style, as always."
 Remember I also have a right to voice my
opinion I'd rather have the Laravel router. Now that's my honest to
goodness opinion if you want something else that is your opinion which you
are entitled to. But until he shows the controller example like I asked the
complete question has not been answered.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164031979
.

And @woodsy1 rather than take the stabs at me, how come you don't put in some ideas, suggestions, code fragments, or whatever to help version 3. You're welcomed to skip over the comments above you do not want to read. But just remember a router change is a major thing not some little tiny thing to be taken lightly. But if I could get the controller example I would drop it.

That's a good idea I will start a new issue.

The answer is there it will be exactly the same as you have now. Exactly.
Nothing will change.
I am very interested in reading the comments and helping where I am needed
but in this case he has already answered you a number times but you are not
seeing it.
Please use @tom suggestion and take it to a new thread or message him
privately. Or take hour on advice and customise it yourself.
On Dec 12, 2015 6:53 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

And @woodsy1 https://github.com/woodsy1 rather than take the stabs at
me, how come you don't put in some ideas, suggestions, code fragments, or
whatever to help version 3. You're welcomed to skip over the comments above
you do not want to read. But just remember a router change is a major thing
not some little tiny thing to be taken lightly. But if I could get the
controller example I would drop it.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164033465
.

@tomvlk I dare to say that the thread title is indeed very generous: SMVC restructure So let's restructure it! :)
In other hand, how about to improve the configuration a bit? And to give to SVMC 3.0 a Inflector?
For configuration, I propose the very simple class mentioned in the first post:
namespace Core;

class Config {

    protected static $settings = array();

    public static function get($key) {
        return isset(self::$settings[$key]) ? self::$settings[$key] : null;
    }

    public static function set($key, $value) {
        self::$settings[$key] = $value;
    }

}

It's usage is very simple, and it is very versatile. For example, if you want to do a active Modules list, you can do:
Config::set('modules', array(
    'System',
    'Cron',
    'Center',
    'User',
    'Menu',
    'Page',
    'Template',
    'MediaManager',
    'Contact',
    'WebAudio',
    'WebChat',
    'CDN',
    'Exam',
    'Course',
));

Yep, we can store in it even arrays, in fact, we can store everything that can be stored in a array, and the built-in behavior is global read access. Of course, this is not a replacement of the constants (aka defines), but a companion. For example, we can have the following files:
app/config/bootstrap.php
app/config/config.php
app/config/constants.php
app/config/routes.php

and in public/index.php, instead of standard Config instantiate, just:
require SMVC.'config/bootstrap.php';
require SMVC.'config/routes.php';

The SMVC/config/bootstrap.php can contains some global useful functions, to include the config.php and constants.php and to do the initialization stage. For example, can contains:
use Helpers\Session;

        /**
         * Turn on output buffering.
         */
        ob_start();

        require SMVC.'config/constants.php';
        require SMVC.'config/config.php';

        /**
         * Turn on custom error handling.
         */
        set_exception_handler('Core\Logger::ExceptionHandler');
        set_error_handler('Core\Logger::ErrorHandler');

        /**
         * Set timezone.
         */
        date_default_timezone_set('Europe/Rome');

        /**
         * Start sessions.
         */
        Session::init();

The constants and config file content is oblivious.
That's all! We have a very simple configuration, which can be extended easily, dedicated per (every) application(s).
The second class, the Inflector, is glorious simple and bugs prone:
<?
php namespace Helpers;

class Inflector extends \Doctrine\Common\Inflector\Inflector
{
}

Yep, I propose to use the Doctrine's Inflector, and the integration is trivial. A new line in composer.json and this class.
"doctrine/inflector": "1.0.*",

And a last suggestion about PHPMailer. Why is needed to ship it? It is available in the Composer repositories. For example, we can add in the composer.json file:
"phpmailer/phpmailer": "~5.2"

and to use a simple wrapper class to integrate it in SVMC.
All the best!

What do you think about the possibility of grouping routes?
Router::group('admin', function() {

    Router::get('/', 'App\Controllers\Admin\AdminController@index');
    Router::get('/some', 'App\Controllers\Admin\AdminController@some');
    (...)

});

or the optional second callback
Router::get('some', 'App\Controllers\Auth@isLogin', 'App\Controllers\Some@some');
Router::get('news/(:num)', 'App\Controllers\News@addVisit', 'App\Controllers\News@showNews');

@mickacz First of all, we preferred to show up with a minimal but very efficient and extensible Routing structure, hopping to not be considered too fat (as code) to be accepted as replacement for the ol'good Macaw Son.
But yes, we considered the Route Grouping and we believe that our (proposed) Routing can be easily extended to support that ability.
Eventually, in future, if this Route Grouping present a huge interest from SVMC community, we can implement it native in the base Router and propose it to SVMC community.
In other hand, what you describe in the optional callback is something rather simple to be implemented via a good Auth Service and the via mentioned Events and EventManager.
First one is a typically Controller's Authorization guarding case, easily to be implemented via an Authorize helper, the second one is rather a typical case of Event propagation, IF there is an EventManager, which not exist.
Yet, we can create, with no problems, some simple EventManager for SVMC, if there is enough interest...
All the Best!

@woodsy1  me and @LuckyCyborg  worked it out, didn'the mean any harm, but I like minute detail, I just needed more detail. Are you going to help test some of this stuff and report your findings?  Believe me I know I rant, but with real sites out there, coupled with lots of testing I'very done in the past, I have stood by this framework through thick and thin. Yes major changes makes be very nervous.

Hello, as response to @mickacz, I made an ExtendedRouter class, who support the Route Groups.
namespace App\Core;

class ExtendedRouter extends \Core\Router
{
    private static $routeGroup = '';

    // Constructor
    public function __construct()
    {
        parent::__construct();
    }

    public static function group($group, $callback)
    {
        // Set the current Routes Group
        self::$routeGroup = trim($group, '/');

        call_user_func($callback);
        // Reset the Routes Group to default (none).
        self::$routeGroup = '';
    }

    public function addRoute($method, $route, $callback)
    {
        $method = strtoupper($method);
        $pattern = ltrim(self::$routeGroup.'/'.$route, '/');

        $route = new Route($method, $pattern, $callback);

        array_push($this->routes, $route);
    }

}

This simple Router extension support the group commands just like was requested:
Router::group('admin', function() {
    Router::get('/', 'App\Controllers\Admin\AdminController@index');
    Router::get('/some', 'App\Controllers\Admin\AdminController@some');
});

To activate the ExtendedRouter, we need on Config:
/**
 * Set the Application Router.
 */
define('APPROUTER', '\App\Core\ExtendedRouter');

Like everyone can see, the design of our (proposed) Routing permit an easily and punctually customization and extension of the Routing behavior, without touching the SVMC's System files.
All the best!

@LuckyCyborg  you have
$router = Router::getInstance();

$router->group('admin', function() {
    Router::get('/', 'App\Controllers\Admin\AdminController@index');
    Router::get('/some', 'App\Controllers\Admin\AdminController@some');
});

But what if admin controller is underneath controllers like
$router = Router::getInstance();

$router->group('admin', function() {
    Router::get('whatever/', 'App\Controllers\AdminController@whatEver');
    });

@woodsy1 speaking of routers how is your exhaustive test of the new routing system coming along?

@jimgwhit have you tried it? it looks like it's called by its namespace.
I'm having a few problems with @LuckyCyborg's routes I've commented on the PR for it.

@LuckyCyborg Thanks for the fast reply on the performance. And indeed you don't need multiple route definitions if you have optional paramters. This will reduce the number of routes defined and will reduce time to do the for loop.
I really think that this will improve the router and should be in the new version, as the current router lacks on some features you have implemented.

Have you tried this?, if so how have you got on with it?

I tried it last night with a querystring, haven't tried it with grouping, I'm waiting til all tweaks are finished. @LuckyCyborg let me know in issue #232  when you have all tweaks completed and I will retest. But I will only be basic testing querystring I'll leave it to @daveismyname  to test friendly URL also.

@jimgwhit OK, I will talk with you in #232 and with @daveismyname in #231

@jimgwhit do not belittle me with a comment like that. I am getting very
tired of the comments you are making.
On Dec 13, 2015 4:37 AM, "LuckyCyborg"<EMAIL_ADDRESS>wrote:

@jimgwhit https://github.com/jimgwhit OK, I will talk with you in #232
https://github.com/simple-mvc-framework/framework/issues/232 and with
@daveismyname https://github.com/daveismyname in #231
https://github.com/simple-mvc-framework/framework/pull/231
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164170726
.

No @woodsy1 any help testing new stuff would be good. You might use the framework in a way I don't, as stated I only tested for querystring. If you are using friendly URLs how about give it a test and let us know if it works. @LuckyCyborg has the latest changes on their forked site now.

And @woodsy1 I would never want to belittle you, I worry about major changes,  may sound argumentative at times, but I do not like that belittle thing. Let's be all in this together.

I have done some testing but mostly around the usability with git. It seems
a lot people don't use git so I have been spending my time preparing some
material for a tutorial on that which will hopefully massively help people
with deployments!
On Dec 13, 2015 10:33 AM, "jimgwhit"<EMAIL_ADDRESS>wrote:

And @woodsy1 https://github.com/woodsy1 I would never want to belittle
you, I worry about major changes, may sound argumentative at times, but I
do not like that belittle thing. Let's be all in this together.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164201862
.

I've accepted the PR for the new router works a lot better than the previous version.
Also I've added a paths.php file under public that define absolute paths:
/** Define the absolute paths for configured directories */
define('APP', dirname(__DIR__).'/app/');
define('SYSTEM', dirname(__DIR__).'/system/');
define('PUBLICDIR', dirname(__FILE__).'/');
define('ROOT', dirname(__DIR__).'/');

the paths inside index.php have been removed and replaced with a require
require('paths.php');

The SMVC constant has been renamed to APP since it maps to the app directory. All referenced to SMVC have been updated.
Some items discussed previously not yet implemented is group routes and assets serving, I think both are good suggestions and would like to implement them with @LuckyCyborg's help.
Also @tomvlk I'd like to look at your proposal too I haven't forgot about the services, correct me if I'm wrong but this appears it would work as an additional classes so getting it setup should be a fairly quick process.
@woodsy1 thanks that's great I'll get the tutorial thread setup on the forum.

@daveismyname with the router on your thoughts, did you remember to put the logger-memory PR in the ver 3 beta yet?

Yes that was accepted shortly after it was opened

@daveismyname  see issue #233 please, but get some more rest.  You had a hard day with that router thing.  Now sleep.

@woodsy1 you mentioned
I have done some testing but mostly around the usability with git.
Does git also work when uploading to a shared host like Godaddy?

That is exactly what I have been testing :)
It will change your life!!
On Dec 13, 2015 3:50 PM, "jimgwhit"<EMAIL_ADDRESS>wrote:

@woodsy1 https://github.com/woodsy1 you mentioned
I have done some testing but mostly around the usability with git.
Does git also work when uploading to a shared host like Godaddy?
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164223291
.

Let us know where the tutorial is once complete please.

It will be on the forums in the new tutorial section Dave has setup. I have
started helping Dave out with the forums so he can focus on the framework
On Dec 13, 2015 3:59 PM, "jimgwhit"<EMAIL_ADDRESS>wrote:

Let us know where the tutorial is once complete please.
—
Reply to this email directly or view it on GitHub
https://github.com/simple-mvc-framework/framework/issues/222#issuecomment-164223493
.

Thanks, I am better now, that router thing was driving me to madness. But all worked out.