bolt / bolt

Bolt is a simple CMS written in PHP. It is based on Silex and Symfony components, uses Twig and either SQLite, MySQL or PostgreSQL.
MIT License
4.15k stars 811 forks source link

Bolt as vendor app #894

Closed rixbeck closed 10 years ago

rixbeck commented 10 years ago

Hello Guys!

First of all let me send my congratulations, this is the most promising CMS project that I've ever seen. I'm seriously thinking about integrating under my webapp projects which need some CMS functionality. I thought I was integrating Bolt as a composer based vendor component. Documentation doesn't mention how to do this so I did as usual. I was implementing Bolt as a required dependency in my app's composer config and after a successful install and webserver setup I was instantiated Bolt's browser based initialization process, first without success. Digging the bootstrap.php and lowlevelchecks.php I can see it is expecting some folders in host application's root. ( /config, /web, etc.) I think bolt has not prepared for this situation when it is a subproject. With some quick and dirty modification it can be easily modifiable but I think it may be worth implementing this situation also. Or did I miss something?

bobdenotter commented 10 years ago

Hi,

There once was a semi-authorative way to do that, but I guess we haven't been keeping a close eye on that. For ourselves, we prefer to use Bolt "as the product" instead of "a module in the app", if you understand what I mean.

See here: http://dev.richardhinkamp.nl/blog/installing-bolt-with-composer

If you want to make this up-to-date and more robust (with docs!), I'll gladly merge that in! :-)

rixbeck commented 10 years ago

Thanks for explanation and for important informations. I'm going to check it out. Thinking about solution...

rixbeck commented 10 years ago

Because constants requires bootstrap.php (and others) like _BOLT_WEBDIR, _BOLT_PROJECT_ROOTDIR, etc can be defined in index.php, moreover in host application's composer configuration also can define _bolt_webdir (as target of Bolt\Composer\ScriptHandler::installAssets) I think there is no reason to modify code. _themepath and _BOLT_CONFIGDIR are configurable as well so I'm closing this issue.

helderco commented 10 years ago

I actually think we should keep this open for discussion because I've been using Bolt in vendor for a while and I've hit a lot of bumps because of Bolt's assumptions on paths, so this isn't "ready" in my opinion.

I very much prefer to keep Bolt as a dependency in vendor and keep my own code separate, while also leaving this code out of the public web folder.

I've just started a new project on 1.5.1 and I have broken stuff so this time around I think I'm ready to contribute back and fix some of the assumptions to allow Bolt to be used as a vendor app for those who want it.

rixbeck commented 10 years ago

I've been succesfully managed this. I made just my own index.php with defines in and everything runs fine while Bolt is dependency in my project config and finally takes place in vendor folder. Does it helps if I share my case with you?

helderco commented 10 years ago

There are some issues, which are hardcoded in parts of Bolt's code. You can't go past them without making hacky code or changing core. I'll send a PR with some fixes and you'll understand.

Here's my web/index.php:

<?php

// "Installing Bolt with Composer: http://rayofsolaris.net/blog/2013/installing-bolt-with-composer"
require_once realpath(__DIR__.'/../vendor/bolt/bolt/app/bootstrap.php');

// Register service providers
$app->register(new \My\Provider\TranslationServiceProvider());
$app->register(new \My\Provider\AuthServiceProvider());

// Register an error handler for 404 aborts
$app->error(array(new \My\ErrorHandler($app), 'http'), -7);

// Enable extensions
$extensions = new \My\Extensions($app);
$extensions->enable("MyExtension");

if (preg_match("~^/thumbs/(.*)$~", $_SERVER['REQUEST_URI'])) {
    // If it's not a prebuilt file, but it is a thumb that needs processing
    require __DIR__ . '/bolt-public/classes/timthumb.php';
} else {
    // Here we go!
    $app->run();
}

My custom code:

app
|-- extensions
|   `-- MyExtension
|       `-- extension.php
|-- resources
|   `-- translations
|       `-- pt
|           `-- messages.pt.yml
`-- src
    |-- Auth.php
    |-- BaseController.php
    |-- Controller.php
    |-- ErrorHandler.php
    |-- Extensions.php
    `-- Provider
        |-- AuthServiceProvider.php
        `-- TranslationServiceProvider.php

I replace my vendor name with "My" when pasting here. That namespace is targeting app/src in composer.json.

Yeah, share your case. Maybe there's something I can use :)

rixbeck commented 10 years ago

Do I understand right, you're going to hold your extensions, resources, etc. separately from Bolt? I didn't care about too much so I'm using composer's post-install-cmd to relocate some necessary resources. I think extensions has right place under bolt at runtime while your customized controllers could be loaded from outside of vendor dir. Config dir location can be define in index.php. Do I miss something?

rixbeck commented 10 years ago

Tomorrow I can compare to my situation and I'll send more details.

rixbeck commented 10 years ago

I've been updated my Bolt to the latest master. This is my index.php:

<?php

use core\Common\LightWork;
// If you wish to put the folder with the Bolt configuration files in another location than /app/config/,
// define it here as a constant. If you do not define it here, the default location is used.

define('BOLT_PROJECT_ROOT_DIR', dirname(__DIR__));
define('BOLT_COMPOSER_INSTALLED', true);
define('BOLT_WEB_DIR', __DIR__);
define('BOLT_CONFIG_DIR', BOLT_PROJECT_ROOT_DIR . '/brix/bolt/config');
define('BOLT_CACHE_DIR', BOLT_PROJECT_ROOT_DIR . '/vendor/bolt/bolt/app/cache');

if ('cli-server' === php_sapi_name()) {
    $filename = __DIR__ . preg_replace('#(\?.*)$#', '', $_SERVER['REQUEST_URI']);

    // If it is a file, just return false.
    if (is_file($filename)) {
        return false;
    } elseif (preg_match("~^/thumbs/(.*)$~", $_SERVER['REQUEST_URI'])) {
        // If it's not a prebuilt file, but it is a thumb that needs processing
        require dirname(__DIR__) . '/vendor/bolt/bolt/app/classes/timthumb.php';
        return true;
    }
}

require dirname(__DIR__) . "/vendor/autoload.php";
require_once dirname(__DIR__) . "/brix/core/Common/LightWork.php";

// bootstrap for host project
$lightWork = new LightWork();
$lightWork->init();

require_once dirname(__DIR__) . '/vendor/bolt/bolt/app/bootstrap.php';

$lightWork->installService($app);
// Here we go!
$app->run();

This is part of my config from /brix/bolt/config/config.yml

...
# The theme to use. Be sure to copy the theme/base-2013 folder, and change the
# name here accordingly. Don't edit the templates in theme/base-2013, because
# they _will_ get updated in next releases
theme: base-2013

theme_path: /web/theme/
...

My project structure:

/
├── brix
│   ├── bolt
│   │   └── config
│   ├── core
│   │   ├── Common
│   │   ├── Components
...
├── tests
│   ├── brix
│   ├── core
│   │   ├── Common
│   │   ├── Components
...
├── vendor
...
│   ├── bolt
│   │   └── bolt
│   │       ├── app
│   │       │   ├── cache
│   │       │   ├── classes
│   │       │   ├── config
│   │       │   ├── database
│   │       │   ├── extensions
│   │       │   ├── resources
│   │       │   ├── src
│   │       │   ├── tests
│   │       │   ├── theme_defaults
│   │       │   └── view
│   │       ├── files
│   │       ├── tests
│   │       └── theme
...
└── web
    ├── bolt-public
    │   ├── classes
    │   │   └── upload
    │   └── view
...
    ├── files
    └── theme

BOLT_PROJECT_ROOT_DIR name is a bit misleading in this situation because it is refers to root folder of entire project. I'm using Bolt's HTTP routing and implemented my own controller for serving HTTP and Ajax requests. At this moment I have no issues found regarding this. update: Although I haven't used Nut yet but as I can see your patch seems to be correct. I'm going to check how does lib.php mods affects behavior.

rixbeck commented 10 years ago

Helder, I checked it with your lib.php patch and seems working as expected.