I'm building a website with Symfony2 and PostgreSQL (for the first time). I've recently discovered the database layer called Pomm, I decided to use it instead of Doctrine2.
However I get a Fatal Error Exception when I try to display some data. The problem might come from a wrong path to the generated Pomm map file. Unfortunately I haven't found any help in the Manual and the tutorials I read to fix my mistake.
Here is what I did:
1- PommBundle Installation into Symfony2.3.1 with Composer = ok
2- Setup (PommBundle registration in the application kernel + database settings) = ok
3- Map file generation for the db table 'product' (as follows) = ok
app/console pomm:mapfile:create product
Pomm generated the folder 'Database' and now the website structure is:
-- Source Files
|-- Database
|-- PublicSchema
|-- Base
ProductMap.php
Product.php
ProductMap.php
|-- app
|-- bin
|-- src
|-- vendor
|-- web
4- app/autoload.php
The PommBundle Documentation about autoload.php is a bit confusing (for a non-native English speaker). Indeed, here's what is written:
If you are using Symfony 2.0.x, you may still be using sf2 autoloader.
Update your app/autoload.php file.
However I'm using Symfony 2.3.1 that's why I thought I don't have to update the app/autoload.php file.
Moreover it's not very clear what you have to add into the file:
# app/autoload.php (original file)
use Doctrine\Common\Annotations\AnnotationRegistry;
use Composer\Autoload\ClassLoader;
$loader = require __DIR__.'/../vendor/autoload.php';
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));
return $loader;
The PommBundle documentation says:
Update your app/autoload.php file [by adding the following code]:
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
...
'Pomm' => __DIR__.'/../vendor/pomm/pomm',
'Pomm\\PommBundle' => __DIR__.'/../vendor/pomm/pomm-bundle',
I didn't understand how I could add this code to my file (shown above). So I guessed this was only for Symfony 2.0.*.
5- Problem in the Controller
In the COntroller I typed the path to the Pomm map file as follows:
namespace Admin\ProductBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class DefaultController extends Controller
{
public function indexAction()
{
$myproducts = $this->get('pomm')
->getDatabase('database')
->createConnection()
->getMapFor('Database\PublicSchema\Product')
->findAll();
return $this->render('AdminProductBundle:Default:index.html.twig',
array("myproducts" => $myproducts));
}
}
I've certainly done something wrong because I get this error:
FatalErrorException: Error: Class 'Database\PublicSchema\ProductMap' not found in
/var/www/mywebsite/vendor/pomm/pomm/Pomm/Connection/Connection.php line 153
I'd be very grateful for any help. Thanks.
The problem is in namespacing.
Symfony trying to call class MyDatabase\PublicSchema\ProductMap that should be located in MyDatabase/PublicSchema/ProductMap.php file whereas your file located in Database/PublicSchema/ProductMap.php
So you should rename the Database folder to MyDatabase ot Database name to Database.
Related
I have a web.py server hosted on pythonanywhere.com doing some handy things with python.
Now I'd like to just serve a straightforward html file from the same server i.e. just return the contents of a static html file to the client
The comments/answers below state that it should be possible, out of the box, to serve static files in the static directory, located in the same directory as the main python file which contains the following :
import web
urls = (
'/', 'hello'
)
app = web.application(urls, globals())
class hello:
def GET(self):
return 'Hello, Joe'
if __name__ == "__main__":
app.run()
The server above works fine, when I go to http://myhost/ it displays "Hello , Joe".
The directory static exists and contains a file small.jpg but when I try the url http://myhost/static/small.jpg it gives me "not found"
Previous text of question up to Nov 9th 2022 is below :
original question title : Trying to return a html file in web.py but getting "No template named ....." error message
So I've looked at the web.py documentation on serving static files and templating and I think the following code should work :
import web
render = web.template.render('static/')
# have also tried render = web.template.render('/full/path/to/static/')
urls = (
'/getlatlongEIRCODE', 'getlatlongEIRCODE', #other stuff
'/getlatlongGOOGLE', 'getlatlongGOOGLE', #other stuff
'/getmonthlyPV', 'getmonthlyPV', #other stuff
'/Tomas', 'Tomas',
)
class Tomas:
def GET(self):
return render.Tomas()
I have created a folder static at the same level as my file above (which works fine for the other scripts) and i have created a file Tomas.html in the static folder containing
<h1>Help me</h1>
However I get an error message when I go to https://example.com/Tomas
<class 'AttributeError'> at /Tomas
No template named Tomas
P.S. From the static files page it seems to say I should just be able to put the Tomas.html file in a folder called "static" and then access is via https://example.com/static/Tomas.html but that is not working (it returns "not found")
You're using a relative path to your template directory without paying attention to the working directory. See https://help.pythonanywhere.com/pages/NoSuchFileOrDirectory/
You're working too hard. 'static' is built in.
As the documentation says, http://localhost/static/logo.png will return the file logo.png from the existing directory static, which is relative to your webserver root.
Do not use render() for this (not needed). Also, do not list your desired file ('/Tomas') in the urls list (not needed).
Anything under the static directory can be accessed with the url https://localhost/static/...
"static" is hardcoded in the web.py server, so you cannot (easily) change this to some other folder. The suggestion in the web.py documents is to have nginx or apache host your application and use an Alias there to go to web.py static. (I think you can also add StaticMiddleware to your web.py application, but you'd need to investigate that yourself -- look at web.application.run()
The case of the disappearing /static/ directory was related to the fact that I'm hosting on pythonanywhere.com
Even though the web.py documentation says that the /static/ folder is plugged in by default, that's not the case in pythonanywhere and you need to expressly make the link between the url http://yourhost/static/ and /path/to/static in the Web part of the dashboard.
There is an option in the menifest file to call method during module installation. We can mention pre_init and post_init.
I would like to call one method while upgrading the module as similar to pre_init. because after module gets installed pre_init will not be called.
Any suggestion for this ?
Why I need this ...
I have a stored procedure to generate report data quickly which uses postgresql stored procedure, now when there is a slight change in the procedure I would like to update it thourh the module upgrade process.
There should be some option available to call method during upgrade module as like pre_init and post_init.
I tried following methods to do this.
# Added following code in XML file
<function model="sale.order" name="action_custom_method"/>
#api.model
def action_custom_method(self):
# stored procedure code
return True
But this is not working for me, I am Using odoo 14.
in Odoo 14 it became pre_init_hook & post_init_hook. which would be set in the __manifest__.py
{
'pre_init_hook': pre_init_hook_method,
'post_init_hook': post_init_hook_method,
}
you also add the method definition in __init__.py
def pre_init_hook_method(cr):
env = api.Environment(cr, SUPERUSER_ID, {}) # to get env
def post_init_hook_method(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {}) # to get env
you may also use the migrations folder & module versioning like what is mentioned there Data Migration
so in your module folder you would have a migration folder. as the following structure:
<moduledir>
`-- migrations
|-- 1.0
| |-- pre-update_table_x.py
| |-- pre-update_table_y.py
| |-- post-create_plop_records.py
| |-- end-cleanup.py
| `-- README.txt # not processed
|-- 12.0.1.1 # processed only on a 12.0 server
| |-- pre-delete_table_z.py
| `-- post-clean-data.py
|-- 0.0.0
| `-- end-invariants.py # processed on all version update
so if your module defined with version like 12.0.1.1 before. you could increment a number to be like 12.0.1.2 in __manifest__.py. later on in your migration folder you add a new folder 12.0.1.2. where you could add pre- or post- python files. which would include you stored procedure definition. please also note that folder 0.0.0 will always run. if that didn't work it could be something else is wrong.
don't hesitate to let us know if you face any problems.
Finally, I got the solution.
We created one .sql file and into that file we added all our stored procedures and other database objects.
We added that sql file in the __manifest__.py
'data': [
'db_function/get_product_sales_history_data.sql',
'db_function/update_product_sales_history.sql',
],
It will execute these sql files at the time of module installation as well as module upgrade time.
After following the composer installation guide for v10 of typo3. I pointed apache vhost to the public folder. Once I navigate to the index.php location in the browser, I get this error
Fatal error: Uncaught ArgumentCountError: Too few arguments to function
TYPO3\CMS\Core\Imaging\IconFactory::__construct()
0 passed in /home/user/projects/typo3/public/typo3/sysext/core/Classes/Utility/GeneralUtility.php
on line 3423
and exactly 2 expected in
/home/user/projects/typo3/public/typo3/sysext/core/Classes/Imaging/IconFactory.php:71
It looks like a dependency injection problem. Please can anybody help with this error
For me this issue occured after moving an existing project from a server into DDEV (which is similar to changing the path/URL by a vhost config). My guess is it has to do with changed paths/URLs in cached files. This is how I solved it:
A) Manually delete all cached files:
t3project$ rm -rf public/typo3temp/*
t3project$ rm -rf var/*
B) Also I had to change the ownership of some autogenerated folders/files to my current user (sudo chown -R myuser:myuser t3project/), then I was able to use the "Fix folder structure" tool in "Environment > Directory Status", now everything was working fine again. Not sure if the last step is helpful for you, as it might be only related to my case where certain folder/files had a wrong owner as they was copied.
I had the same problem today and it occured because I was XClass'ing one of the Core Classes and used GeneralUtility::makeInstance(IconFactory::class) in this code.
The fix is to use DI in this class, just as you suggested. Also flush all caches afterwards to rebuild the DI container.
From this:
class CTypeList extends AbstractList
{
public function itemsProcFunc(&$params)
{
$fieldHelper = GeneralUtility::makeInstance(MASK\Mask\Helper\FieldHelper::class);
$storageRepository = GeneralUtility::makeInstance(MASK\Mask\Domain\Repository\StorageRepository::class);
...
To this:
class CTypeList extends AbstractList
{
protected StorageRepository $storageRepository;
protected FieldHelper $fieldHelper;
public function __construct(StorageRepository $storageRepository, FieldHelper $fieldHelper)
{
$this->storageRepository = $storageRepository;
$this->fieldHelper = $fieldHelper;
}
public function itemsProcFunc(&$params)
{
$this->storageRepository->doStuff();
$this->fieldHelper->doStuff();
...
For future reference for others:
This can also happen in own extensions when the Core uses GeneralUtility::makeInstance on your classes. (e.g. in AuthenticationServices).
The trick here is to make these DI services public like so:
(in extension_path/Configuration/Serivces.yaml)
services:
_defaults:
autowire: true
autoconfigure: true
public: false
Vendor\ExtensionName\Service\FrontendOAuthService:
public: true
Here's documentation for it:
https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ApiOverview/DependencyInjection/Index.html#knowing-what-to-make-public
I had this error because i used the Services.yaml file in one of my extensions, but did not configure it correct.
More infos about the file itself can be found here
Since the file is responsible for the dependency injection, small mistakes e.g. in namespaces lead to the above mentioned error.
To locate the error you can uninstall extensions with a Services.yaml.
When you have found the file/extension, you have to check if all Namespaces in the Classes Directory are correct.
This means:
All filenames are correct regarding the Class they contains
All Namespaces in the files are correct for path and filename
The Namespace can be found via composer. So the extension have to be installed via composer or must have an entry in the autoload list of composer.json
I'm trying to get started with TYPO3 extensions and was following this tutorial to get to see the basics.
In the backend everything works fine, but on the front end I get an error:
Oops, an error occurred! Code: 20170209104827c3b58d58 -
{"exception":"exception 'ReflectionException' with message 'Class
Tx_Inventory_Controller_InventoryController does not exist'
My files are exactly the same as in the tutorial. I have no idea what is causing this. I assume I made some dumb mistake with namespaces, but they seem to be all correct.
The controller class can be found below and is located in typo3conf/ext/inventory/Classes/Controller/
<?php
namespace \MyVendor\Inventory\Controller;
use \TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use \TYPO3\CMS\Core\Utility\GeneralUtility;
use \MyVendor\Inventory\Domain\Model\Repository\ProductRepository;
class InventoryController extends ActionController {
public function listAction() {
$productRepository = GeneralUtility::makeInstance(ProductRepository::class)
$products = $productRepository->findAll();
$this->view->assign('products', $products);
}
}
?>
When developing a new extension in a composer installed TYPO3 V9 (here: 9.4) the autoload part has to be added to the central root composer.json. Found it here (German). Following the steps in the OPs mentioned tutorial leads to a core exception:
Core: Exception handler (WEB): Uncaught TYPO3 Exception: #1278450972:
Class MyVendor\StoreInventory\Controller\StoreInventoryController does not exist.
Reflection failed.
As long as the extension is not installed via composer, e.g because it's newly developed, composer does not find the appropriate composer.json file in the extensions directory. Hence TYPO3 does not find any classes in the new extensions Classes directory. To resolve the issue the autoload configuration has to be added to the root composer.json. Just put the following lines into composer.json within the installations base directory:
{
"repositories": [
{ "type": "composer", "url": "https://composer.typo3.org/" }
],
...
"autoload": {
"psr-4": {
"MyVendor\\StoreInventory\\": "public/typo3conf/ext/store_inventory/Classes/"
}
}
}
Then regenerate the autoload configuration:
composer dumpautoload
You possibly have to clear the cache as well in the backend.
It looks like your class is not autoloaded. If you don't use composer to make your autoload, take a look in your typo3conf/autoload/autoload_classmap.php file.
You should find an entry corresponding to your file. You will see if you have a path error.
Remove backslashes - try with
<?php
namespace MyVendor\Inventory\Controller;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use MyVendor\Inventory\Domain\Model\Repository\ProductRepository;
class InventoryController extends ActionController {
public function listAction() {
$productRepository = GeneralUtility::makeInstance(ProductRepository::class)
$products = $productRepository->findAll();
$this->view->assign('products', $products);
}
}
Ensure you add Vendorname to extension key, when you register your plugin, see ext_tables.php and write 'MyVendor.'.$_EXTKEY instead of $_EXTKEY like
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'MyVendor.'.$_EXTKEY,
'List',
'The Inventory List'
);
I had exactly the same problem - it happens if Typo3 installation is done by composer. To solve this problem see this page of the docs.
Try to add autoload in your ext_emconf.php (replace 'Vendor\\Extensionkey\\') and uninstall and install your extension again (to rebuild PHP autoload information)
'autoload' =>
array (
'psr-4' =>
array (
'Vendor\\Extensionkey\\' => 'Classes',
),
),
'_md5_values_when_last_written' => 'a:0:{}',
'suggests' => array(
),
I get the following error messages:
Warning: include_once(Zend\Db.php) [function.include-once]:
failed to open stream: No such file or directory in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 83
Warning: include_once() [function.include]:
Failed opening 'Zend\Db.php' for inclusion (include_path='VPZ/') in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 83
Warning: require_once(Zend/Exception.php)
[function.require-once]: failed to open stream:
No such file or directory in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 87
Fatal error: require_once() [function.require]:
Failed opening required 'Zend/Exception.php' (include_path='VPZ/') in
C:\EasyPHP3\www\VPZ\Lib\Zend_1.7.7\Loader.php on line 87
i want to include ZendXXX\Db.php
how to change it
create a directory (say 'lib'), and put your Zend directory in it. so your directory structure looks like this:
- application
- lib
|- Zend
- wwwroot
|- index.php
now you should add lib to your include path. edit your index.php file:
$includePath = array();
$includePath[] = '.';
$includePath[] = './../application';
$includePath[] = './../lib';
$includePath[] = get_include_path();
$includePath = implode(PATH_SEPARATOR,$includePath);
set_include_path($includePath);
now you have your lib in your include path. you can include all Zend components like this:
include 'Zend/Loader.php';
require_once 'Zend/Db.php';
the best way is too include Zend_Loader first and then use it to load classes. do this:
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Db');
you can also register to autoload classes. just add this line to your code after all those before:
Zend_Loader::registerAutoLoad('Zend_Loader',true);
now you do not need to include files to call classes. just instanciate your classes:
$session = new Zend_Session_Namespace('user');
there is no need to include 'Zend/Session/Namespace.php'.
Use set_include_path(). See PHP.net documentation
Example:
set_include_path(get_include_path() . PATH_SEPARATOR . '/path/to/Zend');
I usually store the framework files under a "library" folder:
application
public_html
library
Zend
Common
etc....
and then in my bootstrap file, or front controller, I add that "library" folder to the include path:
set_include_path(get_include_path() . PATH_SEPARATOR . '../library');
See also:
Choosing Your Application's Directory Layout.
Create the Filesystem Layout.
The reason the other suggestions say anything about doing that, is because it's a bad move - in other words, you're doing it wrong.
You can create a subdirectory and name it Zendxxx, but then you have to add that to your include_path, and change it, whenever you put a newly named version up.
I'd hazard a guess, and say that you don't have a good way to test the website (so you want to lock it to a particular version of ZF), and further, that you aren't using revision control, so you want all the previous versions of code in the site-directory to be able to go back to, if you find a problem when you change the live-running code directly on the server.
project without library And including library from one location
project C:\xampp\htdocs\my\application
library C:\xampp\Zend\library
make changes in index.php
// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR,
array(realpath(APPLICATION_PATH.'/../../../Zend/library'),get_include_path(),)));