Just open sourced my 10k LOC PHP & MySQL invoicing app
github.com
github.com
//CI Class Load Example:
$this->load->library('example'); $this->example->something();
//Raw PHP Class Load Example:
$this->example = new Example(); $this->example->something();
As you can see, the latter is a little more obvious about what is going on.
Also another question would be which frameworks is he currently using and what are its advantages.
I did start rebuilding this in Kohana a few months ago with the intention of rebuilding it as a less panel-y looking interface, but ended up scrapping the project.
[0]. http://symfony.com/ [1]. http://silex.sensiolabs.org/ [2]. http://www.doctrine-project.org/
I've dabbled in Doctrine before, but the memory usage looked a little too high for the convenience it offered.
It's a rather different beat, but you might checkout Propel (http://propelorm.org) for a different take on a PHP ORM. It has a static build phase unlike Doctrine which turns some people off, but if you can get past that it's a rather nice ORM.
A lot about their active record implementation violates POLA with various gotchas and code generation gets tedious and unwieldy with models that contain many fields or relations.
Say you want to add a product to an existing order in the database...
$orderProduct = new OrderProduct(); $order = OrderPeer::retrieveByPK(1);
$order->addOrderProduct($orderProduct);
Now, if ANYWHERE after this point in the code, something calls $order->getOrderProducts() before you call $order->save() (like a validation routine or something) you will lose that new OrderProduct and it will not be persisted.
It's bit me more than once, especially as you start to spread code around that depends on traversing the relationships - can be a very tricky bug to spot.
If you want to make it easier for other people to come on, perhaps open up to an ecosystem of open source contribution, you want a framework with broad appeal. Yii or Drupal would be good choices.
If you want a solid foundation, that you personally will benefit from, you either want something that is well engineered (perhaps even slightly over engineered) or something really minimal, that doesn't get in the way. Depending on you own experience and/or taste.
Or that macros without bounds checking that cause segfaults unless debugging is a good idea...
What was I thinking?
You can also throw comments in the code where the bad stuff is so that it has more visibility, as well as suggestions for how to better solve the problem. Sometimes people learn best from bad code!
It should sound scary, it's the worst code I've ever written.
I wrote it 2 years ago with the idea "working first, correct later", but I haven't finished the latter yet...
One of them was SMOKE[1] - simple Python/Flask site with login. The most interesting part is probably the SMF Forum signature rotator[2], which manually parses HTML[3] that is not intended to be machine-readable.
[1]https://github.com/TazeTSchnitzel/SMOKE
[2]https://github.com/TazeTSchnitzel/SMOKE/blob/master/smoke/sm...
[3]https://github.com/TazeTSchnitzel/SMOKE/blob/master/smoke/sm...
Am I doing something wrong? Notes or something?
Otherwise, you get this ugly term: embezzlement.
But kudos for opensourcing it and standing up to criticism from hecklers like me.
A product with as much depth would likely appeal to accountants or those that assist them directly.
But still within the core area, I think you have to accept that I would trust your books if they were kept in pencil more than I would trust books kept with software that didn't have proper controls.
There was also a fear of letting this be my full time gig and not having a steady paycheck. My brick and mortar business had just closed its doors as my biggest client stopped paying people (he literally disappeared into the woods and had a class action lawsuit from many people he owed money).
Here's mine: http://redtagcrazy.com/blog/2011/03/28/rise-and-fall/
One thing you could do is write a really good invoicing app that works with a decent GAAP accounting system, like LedgerSMB. If the system is ok, and the database underneath is solid, you can do the GAAP stuff without having to write a whole accounting package.
the web based invoicing market is extremely crowded and very hard to complete against the likes of freshbooks.com
though i went the opposite route to you and its working $ for me
created the open source app http://simpleinvoices.org first, got large user based, then offered premium hosting at http://smarterinvoices.com
I think the difficulty with invoicing is that it is so heavily tied to everything else one might try to do in a business, from tracking inventory to CRM to financial accounting. This doesn't mean that one can't do this, but the interconnections seem to be key.
re interconnections
* depending on the target market
* the people who need integration already do some form of accounting already - and a 'full stack' accounting solution like http://xero.com is more appropriate for this market
* simpleinvoices market is people with no accounting system or desire for debit/credit stuff so we have make no attempts to make quickbooks, etc. integration work
If I'm wrong, please do let me know!
Any pull request to fix a vulnerability will be happily accepted!
in: controllers/invoice.php
$data['invoices'] = $this->invoice_model->select_multiple($this->session->userdata('company_id'), $page, $this->pref_user['per_page'], TRUE, $sort_col);
$sort_col appears to be just uri_segment 2 of list_items.
select_multiple() then calls:
$sql = "SELECT id, name, DATEDIFF(NOW(), duedate) AS past_due FROM invoice WHERE company_id = " . $this->db->escape($company_id) . " ORDER BY $sort_col";
$sort_col is left as-is. It is certainly more difficult, since '()' aren't permitted in the uri, and we're already in the ORDER BY clause, but I think it may still be doable to get some blindsql into there.
CI strips out all funky characters, so while it is possible to cause an erroneous query, I'm not seeing a security issue here.
I would encourage you to consider trying hard to build a team around your project. In my experience open source software is hard work and really only can thrive in a community. This doesn't form magically around the software. It takes time and effort to build. If you can get good security folks in your community you can learn a lot from them.
http://neoinvoice.local/invoice/list_items/1/asdf
Does cause an erroneous query. It should use a case statement to check against column names. CI will strip out any special characters though.
Tried using it recently and it actually was quite nice despite the lack of docs and other various hiccups.
At any rate, thanks for putting it out.
Now as for this application being written in Code Igniter? I don't really see it as a problem since it means it will be easier for lesser experienced dev to pick up and run with the ball. In time they will learn it's major deficiencies and they will move on. But i think there is room for improvement, in fact I think this would be a great project to port to another maybe more robust framework and is a good project for learning new framework translations.
I will say however that the author wanting to rewrite a product like this in nodejs is really only going to make something like this more inherently difficult to maintain since javascript code tends to get more complicated than your typical java / php / python app as it grows. Granted you do have js at your finger tips it is still largely un-tested on massive scale for large application development. It however has shown great promise for handling extreme traffic in terms of concurrency, but it handles it mostly by using async libraries which pile everything into queues of some sort some where. So your code is littered with async callbacks everywhere. Anyways.. Not only that, but the biggest problem of all is the inability to intelligently step through your code with some kind of IDE beyond using a browser-base debuger such as webkit inspector or the online IDE cloud 9.
I don't hate nodejs. I just think people are jumping on the band wagon way too quickly for server-side hosting. For websockets it's a great solution, I just don't like seeing it as "the only solution" for some peoples projects. I'd rather see a more hybrid approach.
I'm used to selling items on the Envato marketplace, which provides all of the 'advertising' for me. But it seems that with Flippa, there is so much noise and one has to do their own finding of buyers.
Did you never charge? Or were you charging? What were the reasons it was / you were not ready to make it a money making business? Any mistakes or lessons learned while building/running the software? Where did the 120 users come from?
As someone who is looking to create their own product soon I'd be really grateful for any response you can give.
Thanks
Alan
The most advertising I did do was a 125x125 ad on a website used by web developers (DavidWalsh.name) for one month. I didn't get a single user through that ad though.
The biggest lesson learned is that an app like this really needs someone who is good at marketing. I'm just a programmer, but if I had found a marketer and pursued the development of the app, I'm pretty sure it could have been successful.
Another take away is to research competitors. I never looked them up since I actually built this mostly for myself at first, and just kept adding new features as it got bigger. It turned out the market was very crowded (This page has a list of 17 competitors: http://thomashunter.name/blog/shutting-down-and-open-sourcin...).
Also, "piss or get off the pot". I spent a lot of time developing this but I didn't devote enough of my time to it for it to be successful.
Also I know you're getting a lot of stick in this thread for the code which I feel is unjustified, I just want to say I commend you for open sourcing it.
Also, the CI framework isn't all that great, I would have certainly used a different framework. Perhaps even Node.js (which is what I'm doing a lot of my development in nowadays).
I also would have looked for a marketer and devoted more time to the project. The market for this kind of product is very crowded, but there is a lot of room for innovation.
You can say all you want about invoicing being an over saturated market, but I launched a very successful project management product a few months ago. Focus on doing a few things very well, and you can do well in just about any "saturated" B2B space.
Besides, this was a personal project, probably created without the intention of eventually open sourcing it. If he only ever intended to use MySQL, and portability across RDBMS systems wasn't a goal, then it's fine as it is.
Seriously though I agree with your point about PDO. Perhaps the down-vote was due to the comment about de-engineering and apparently making fun of 10k LOC?
I took a look at the app and it's got a huge amount of features. 10k is not really that much code for a "enterprise" app I suppose you could call it. The OP probably is just trying to express the amount of labor that went into the app. Unfortunately other developers may judge your LOC as either a positive or negative, so it's probably best to avoid mentioning it (unless you've written an app in an unbelievably low number of lines).
Here is the suggested CI method for executing database queries: http://codeigniter.com/user_guide/database/examples.html
Nowadays, I prefer (PHP) frameworks with real autoloaders and better OOP usage (like Zend or Kohana).
Make a pull request, sir.
http://www.php.net/manual/en/intro.pdo.php
In this sense, wouldn't it have been better to either recommend that he should have used a DBA library? Or even recommend that he used PDO in place of CodeIgniter's own DB access library?
The OP's experience aside, I think you're also missing that this was written on top of CodeIgniter. From my own experience and learning, CodeIgniter isn't really the best tool for writing larger applications. It's architecture isn't so great and is largely a remanent of the past. To end a rant about CodeIgniter short, it seems more natural to write namespaced procedures using classes rather than taking full advantage of objects and OO (again, probably due to it being largely a PHP4 framework).
Plus, I really disagree with his comment.