typo3 php file in public folder access controller function - php

is there any posibillity to access a controller function from a php file that is based in resource/public/php/file.php
What I want is this php file is special file I use it for this:
<img src="file.php"></img>
I will disable readable paths. So this php file does some encryption and need a connection to a normal controller function.
thanks

is there any posibillity to access a controller function from a php file that is based in resource/public/php/file.php
Yes, it is possible but therefor you need to bootstrap the TYPO3 core as well. Or if it is a static and public method than you can call it directly.
But this seems not the right way to do it in your case.
Assuming you're working on some kind of captcha thing you should consider your own page type for rendering the dynamic images. Here's a working example:
TypoScript Setup
In TypoScript we're registering our own page typ and pointing it out to our extension, controller and action:
DynamicCaptchaImage = PAGE
DynamicCaptchaImage {
typeNum = 1234
10 = USER_INT
10 {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
pluginName = Pi1
extensionName = MyExtName
vendorName = MyCompanyName
controller = MyExtbaseController
action = renderCaptchaImage
# view =< plugin.tx_myextname.view // you provide the view yourself
# persistence =< plugin.tx_myextname.persistence // in case you need a repository you should uncomment it
settings =< plugin.tx_myextname.settings
}
config {
disableAllHeaderCode = 1
additionalHeaders = Content-Type: image/png
xhtml_cleaning = 0
admPanel = 0
debug = 0
}
}
See also: Registering a custom typeNum-based Controller access
Controller
Here's an example how your controller and action should look like:
<?php
namespace MyCompanyName\MyExtName\Controller;
/**
* MyExtbaseController
*/
class MyExtbaseController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {
/**
* Render Captcha Image Action
*
* #return void
*/
public function renderCaptchaImageAction() {
// Send some headers
header('Content-Type: image/png');
// < do your magic stuff here >
// Breaks the script because we've sent already some headers and want
// to prevent that TYPO3 is adding another stuff (eg. for debugging purposes)
// that can break the image from loading.
// return FALSE; does not stop doing that!
exit;
}
}
See also: Extbase wiki
Accessing the controller
Now we've configured the custom page type we're allowed to access the controller by calling the page type given in the TypoScript setup.
Eg. http://www.example.com?type=1234 points out to the renderCaptchaImageAction() in the MyExtbaseController.
Fluid
In Fluid you can link to the page type you've configured by:
<img src="{f:link.page(pageType: 1234)}" />
See also: Fluid wiki
Realurl
If you're using the extension realurl you can change ?type=1234 to captcha.png by:
// [...]
'fileName' => array(
'index' => array(
'captcha.png' => array(
'keyValues' => array(
'type' => 1234,
),
),
),
),
// [...]
See also: Realurl wiki

Related

TYPO3 7.6.10: How to extend the felogin extension?

I tried to extend the core extension felogin with an extra extension called "feloginextended".
I want to add the first_name and the last_name property of the current user into my logout formular.
This is my overridden template (only the logout part):
<!--###TEMPLATE_LOGOUT###-->
<form class="login-form" action="###ACTION_URI###" target="_top" method="post">
<div>
<div class="user">###FIRSTNAME### ###LASTNAME###</div>
<a class="page-link-button" href="http://tf.lightblue.eu/index.php?id=14">Meine Siegel</a>
<a class="page-link-button" href="http://tf.lightblue.eu/index.php?id=15">Mein Account</a>
<input class="form-btn" type="submit" name="submit" value="Logout" />
</div>
<div class="felogin-hidden">
<input type="hidden" name="logintype" value="logout" />
<input type="hidden" name="pid" value="###STORAGE_PID###" />
<input type="hidden" name="###PREFIXID###[noredirect]" value="###NOREDIRECT###" />
</div>
</form>
<!--###TEMPLATE_LOGOUT###-->
Then I added the Controller Classes\Xclass\FrontendLoginController to my extension.
I copied the original file and add some changes in the showLogout function, to set the markers:
<?php
namespace Typo3\feloginextended\Xclass;
use \TYPO3\CMS\Frontend\Plugin\AbstractPlugin;
/**
* Plugin 'Website User Login' for the 'felogin' extension.
*/
class FrontendLoginController extends AbstractPlugin
{
/**
* Shows logout form
*
* #return string The content.
*/
protected function showLogout()
{
$subpart = $this->cObj->getSubpart($this->template, '###TEMPLATE_LOGOUT###');
$subpartArray = ($linkpartArray = array());
$markerArray['###STATUS_HEADER###'] = $this->getDisplayText('status_header', $this->conf['logoutHeader_stdWrap.']);
$markerArray['###STATUS_MESSAGE###'] = $this->getDisplayText('status_message', $this->conf['logoutMessage_stdWrap.']);
$this->cObj->stdWrap($this->flexFormValue('message', 's_status'), $this->conf['logoutMessage_stdWrap.']);
$markerArray['###LEGEND###'] = $this->pi_getLL('logout', '', true);
$markerArray['###ACTION_URI###'] = $this->getPageLink('', array(), true);
$markerArray['###LOGOUT_LABEL###'] = $this->pi_getLL('logout', '', true);
$markerArray['###NAME###'] = htmlspecialchars($this->frontendController->fe_user->user['name']);
$markerArray['###STORAGE_PID###'] = $this->spid;
$markerArray['###USERNAME###'] = htmlspecialchars($this->frontendController->fe_user->user['username']);
$markerArray['###USERNAME_LABEL###'] = $this->pi_getLL('username', '', true);
$markerArray['###NOREDIRECT###'] = $this->noRedirect ? '1' : '0';
$markerArray['###PREFIXID###'] = $this->prefixId;
// my custom changes-----------------------------------
$markerArray['###FIRSTNAME###'] = htmlspecialchars($this->frontendController->fe_user->user['first_name']);
$markerArray['###LASTNAME###'] = htmlspecialchars($this->frontendController->fe_user->user['last_name']);
//------------------------------------------------------
$markerArray = array_merge($markerArray, $this->getUserFieldMarkers());
if ($this->redirectUrl) {
// Use redirectUrl for action tag because of possible access restricted pages
$markerArray['###ACTION_URI###'] = htmlspecialchars($this->redirectUrl);
$this->redirectUrl = '';
}
return $this->cObj->substituteMarkerArrayCached($subpart, $markerArray, $subpartArray, $linkpartArray);
}
}
Then I register my template in the ext_typoscript_setup.txt file:
plugin.tx_felogin_pi1 {
templateFile = EXT:feloginextended/Resources/Private/Templates/FrontendLogin.html
}
And my final step was the registration of the controller in the ext_localconf.php:
<?php
if (!defined('TYPO3_MODE')) {
die('Access denied.');
}
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Felogin\\Controller\\FrontendLoginController'] = array(
'className' => 'Typo3\\Feloginextended\\Xclass\\FrontendLoginController',
);
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['tx_felogin_pi1'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Felogin\\Controller\\FrontendLoginController'];
If add this changes into the original files of the felogin extension, then I have a solution.
But this way is very dirty and in the future I can't update the felogin extension easily.
I found this "solution": https://forum.typo3.org/index.php/t/202500/
But it don't work for me.
Have anyone an idea or have an other way to bring the first and the last name of the current user to the logout formular?
EDIT:
I get everytime a http error 500!
Thanks Felix
The solution is pretty simple. You can just add the markers ###FEUSER_FIRST_NAME### and ###FEUSER_LAST_NAME### to your template and they will be replaced by the right values. This schema is general and can be used on all fields of the user:
###FEUSER_{DB field in uppercase}###. Note that the fields are used with underscores and not the lower camelcase.
This works in TYPO3 6.x and the code looks the same in 7.6 so it should work too.
Assumed that your extension EXT:feloginextended is installed and you cleared all caches including the full cache clear provided by the install tool, you have done everything correct. Delete also the directory /typo3temp/autoload completely.
The only thing which may be wrong is the loading order of the extensions, which is important in case you define your TS-Setup inside the file ext_typoscript_setup.txt.
In this case you must force your extension to be loaded after the original EXT:felogin extension. And the only way to assure that is to add the extension felogin to the list of "suggests" constraint setting inside EXT:feloginextended/ext_emconf.php.
Then you must fully deinstall your extension and install it again.
$EM_CONF[$_EXTKEY] = array(
[...]
'constraints' => array(
[...]
'suggests' => array(
'felogin' => '7.6.0-7.6.99'
),
)
);
To continue the answer after your error 500 information.
This must be a class loader problem as well, the fact that you are seeing 500 error is caused by PHP or TYPO3 error reporting configuration.
Anyway I copied your approach as follows:
EXT:my_extension/ext_localconf.php
<?php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\CMS\Felogin\Controller\FrontendLoginController'] = array(
'className' => 'Typo3\Feloginextended\Xclass\FrontendLoginController',
);
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['tx_felogin_pi1'] = $GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects']['TYPO3\\CMS\\Felogin\\Controller\\FrontendLoginController'];
EXT:my_extension/ext_typoscript_setup.txt
plugin.tx_felogin_pi1 {
templateFile = EXT:my_extension/FrontendLogin.html
}
EXT:my_extension/Classes/FrontendLoginController.php
<?php
namespace Typo3\Feloginextended\Xclass;
use TYPO3\CMS\Felogin\Controller\FrontendLoginController as BaseFrontendLoginController;
/**
* Plugin 'Website User Login' for the 'felogin' extension.
*/
class FrontendLoginController extends BaseFrontendLoginController
{
/**
* Shows login form
*
* #return string The content.
*/
protected function showLogin()
{
$subpart = $this->cObj->getSubpart($this->template, '###TEMPLATE_LOGIN###');
$subpartArray = ($linkpartArray = array());
$markerArray['###MY_MARKER###'] = 'My new login';
return $this->cObj->substituteMarkerArrayCached($subpart, $markerArray, $subpartArray, $linkpartArray);
}
}
EXT:my_extension/FrontendLogin.html
[...]
<!--###TEMPLATE_LOGIN###-->
###MY_MARKER###
<!--###TEMPLATE_LOGIN###-->
<!--###TEMPLATE_LOGOUT###-->
My New Logout
<!--###TEMPLATE_LOGOUT###-->
[...]
The result is totally correct instead of the login form I see 'My New Login', so everything is working for me.
The solution for you is:
1) You have a typo in the namespace. It must be namespace Typo3\**F**eloginextended\Xclass; instead of namespace Typo3\**f**eloginextended\Xclass;
2) You must inherit from TYPO3\CMS\Felogin\Controller\FrontendLoginController
Do not forget to clear typo3temp/Cache/* and typo3temp/autoload/* !

SilverStripe TInyMCE configuration requires a refresh to take effect

We have built out our own version of the tinyMCE editor in SilverStripe. The only issue is that you need to hit refresh for our custom configuration to be loaded. Once it has been refreshed once, it sticks for the rest of the session.
Our set up is as follows:
BolierplateWYSIWYG.php
class BolierplateWYSIWYG extends Extension {
protected function defaults() {
$defaultEditorConfig = HtmlEditorConfig::get('cms');
$defaultEditorConfig->setOptions(
array(
'theme' => 'advanced',
'priority' => 1,
// More config options
)
);
return HtmlEditorConfig::get('cms');
}
public function getConfig() {
return $this->defaults();
}
}
Then, inside of Page.php we have the following:
... page functions ...
public function getCMSFields() {
$fields = parent::getCMSFields();
// Update WYSIWYG
$digital360Wysiwyg = new Digital360WYSIWYG;
$digital360Wysiwyg->getConfig();
... Page CMS configuration ...
Inside of our boilplate.yml we have:
HtmlEditorField:
extensions:
- BolierplateWYSIWYG
How do I get this new configuration to load without requiring a page refresh?
Like #assertchris mention, my PR https://github.com/silverstripe/silverstripe-framework/pull/4259/files has now been merge so you can easily have multiple TinyMCE configs which should help you with you extension.
Setup your HTMLEditorConfig in _config.php like
HtmlEditorConfig::get('default')->setOptions....
HtmlEditorConfig::get('fancy')->setOptions....
Since you have to have an extension, you could have something like:
class BolierplateWYSIWYG extends Extension {
public function setEditorConfig($name = 'default')
{
HtmlEditorConfig::set_active($name);
}
}
The you can use it like this when setting up your CMS fields
$digital360Wysiwyg = new Digital360WYSIWYG;
$digital360Wysiwyg->setEditorConfig();
or
$digital360Wysiwyg = new Digital360WYSIWYG;
$digital360Wysiwyg->setEditorConfig('fancy');
This should work fine. Although be careful when changing some of the editor options like mode, as this can cause your refresh issue. an you shouldn't have to change theme or priority?
Might want to check this pull request: https://github.com/silverstripe/silverstripe-framework/pull/4259
You can customise your HtmlEditorField by calling setOptions in your _mysite/config.php:
HtmlEditorConfig::get('cms')->setOptions(
array(
'theme' => 'advanced',
'priority' => 1,
// More config options
)
);
This will work without the need to refresh a CMS page.

Zend Framework URL based translation routes

I am trying to implement URL based translation in Zend Framework so that my site is SEO friendly. This means that I want URLs like the below in addition to the default routes.
zend.local/en/module
zend.local/en/controller
zend.local/en/module/controller
zend.local/en/controller/action
The above are the ones I have problems with right now; the rest should be OK. I have added a controller plugin that fetches a lang parameter so that I can set the locale and translation object in the preDispatch method. Here are some of my routes (stored in a .ini file):
; Language + module
; Language + controller
resources.router.routes.lang1.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.lang1.route = "(^[a-zA-Z]{2})/(\w+$)"
resources.router.routes.lang1.defaults.controller = index
resources.router.routes.lang1.defaults.action = index
resources.router.routes.lang1.map.1 = "lang"
resources.router.routes.lang1.map.2 = "module"
; Language + module + controller
; Language + controller + action
resources.router.routes.lang2.type = "Zend_Controller_Router_Route_Regex"
resources.router.routes.lang2.route = "(^[a-zA-Z]{2})/(\w+)/(\w+$)"
resources.router.routes.lang2.defaults.module = default
resources.router.routes.lang2.defaults.action = index
resources.router.routes.lang2.map.1 = "lang"
resources.router.routes.lang2.map.2 = "controller"
resources.router.routes.lang2.map.3 = "action"
As the comments indicate, several URL structures will match the same route, which makes my application interpret the format incorrectly. For instance, the following two URLs will be matched by the lang1 route:
zend.local/en/mymodule
zend.local/en/mycontroller
In the first URL, "mymodule" is used as module name, which is correct. However, in the second URL, "mycontroller" is used as module name, which is not what I want. Here I want it to use the "default" module and "mycontroller" as controller. The same applies for the previous lang2 route. So I don't know how to distinguish between if the URL is of the structure /en/module or /en/controller.
To fix this, I experimented with the code below in my controller plugin.
// Get module names as array
$dirs = Zend_Controller_Front::getInstance()->getControllerDirectory();
$modules = array_keys($dirs);
// Module variable contains a module that does not exist
if (!in_array($request->getModuleName(), $modules)) {
// Try to use it as controller name instead
$request->setControllerName($request->getModuleName());
$request->setModuleName('default');
}
This works fine in the scenarios I tested, but then I would have to do something similar to make the lang2 route work (which possibly involves scanning directories to get the list of controllers). This just seems like a poor solution, so if it is possible, I would love to accomplish all of this with routes only (or simple code that is not so "hacky"). I could also make routes for every time I want /en/controller, for instance, but that is a compromise that I would rather not go with. So, if anyone knows how to solve this, or know of another approach to accomplish the same thing, I am all ears!
I've reproduced your problem here and come out with the following (not using config files though):
Router
/**
* Initializes the router
* #return Zend_Controller_Router_Interface
*/
protected function _initRouter() {
$locale = Zend_Registry::get('Zend_Locale');
$routeLang = new Zend_Controller_Router_Route(
':lang',
array(
'lang' => $locale->getLanguage()
),
array('lang' => '[a-z]{2}_?([a-z]{2})?')
);
$frontController = Zend_Controller_Front::getInstance();
$router = $frontController->getRouter();
// Instantiate default module route
$routeDefault = new Zend_Controller_Router_Route_Module(
array(),
$frontController->getDispatcher(),
$frontController->getRequest()
);
// Chain it with language route
$routeLangDefault = $routeLang->chain($routeDefault);
// Add both language route chained with default route and
// plain language route
$router->addRoute('default', $routeLangDefault);
// Register plugin to handle language changes
$frontController->registerPlugin(new Plugin_Language());
return $router;
}
Plug-in
/**
* Language controller plugin
*/
class Plugin_Language extends Zend_Controller_Plugin_Abstract
{
/**
* #var array The available languages
*/
private $languages = array('en', 'pt');
/**
* Check the URI before starting the route process
* #param Zend_Controller_Request_Abstract $request
*/
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
$translate = Zend_Registry::get('Zend_Translate');
$lang = $translate->getLocale();
// Extracts the URI (part of the URL after the project public folder)
$uri = str_replace($request->getBaseUrl() . '/', '', $request->getRequestUri());
$langParam = substr($uri, 0, 3);
// Fix: Checks if the language was specified (if not, set it on the URI)
if((isset($langParam[2]) && $langParam[2] !== '/') || !in_array(substr($langParam, 0, 2), $this->languages)) { {
$request->setRequestUri($request->getBaseUrl() . '/' . $lang . "/" . $uri);
$request->setParam('lang', $lang);
}
}
}
Basically, there's the route chain for applying the language settings within the module default route. As a fix, we ensure that the URI will contain the language if the user left it out.
You'll need to adapt it, as I'm using the Zend_Registry::get('Zend_Locale') and Zend_Registry::get('Zend_Translate'). Change it to the actual keys on your app.
As for the lang route: [a-z]{2}_?([a-z]{2})? it will allow languages like mine: pt_BR
Let me know if it worked for you.

different module based on hostname

I have build a CMS using Zend Framework (1.11). In the application I have two modules, one called 'cms' which contains all the CMS logic and an other 'web' which enables a user to build their own website around the CMS. This involves adding controllers/views/models etc all in that module.
The application allows you to serve multiple instances of the app with their own themes. These instances are identified by the hostname. During preDispatch(), a database lookup is done on the hostname. Based on the database field 'theme' the app then loads the required css files and calls Zend_Layout::setLayout() to change the layout file for that specific instance.
I want to extend this functionality to also allow the user to run different web modules based on the 'theme' db field. However, this is where I am stuck. As it is now, the web module serves the content for all the instances of the application.
I need the application to switch to a different web module based on the 'theme' database value (so indirectly the hostname). Any ideas?
Well, in my opinion,
You should write a front controller plugin for the web module, and do it so, that when you need another plugin, you can do so easily.
The front controller plugin should look something like this:
class My_Controller_Plugin_Web extends My_Controller_Plugin_Abstract implements My_Controller_Plugin_Interface
{
public function init()
{
// If user is not logged in - send him to login page
if(!Zend_Auth::getInstance()->hasIdentity()) {
// Do something
return false;
} else {
// You then take the domain name
$domainName = $this->_request->getParam( 'domainName', null );
// Retrieve the module name from the database
$moduleName = Module_fetcher::getModuleName( $domainName );
// And set the module name of the request
$this->_request->setModuleName( $moduleName );
if(!$this->_request->isDispatched()) {
// Good place to alter the route of the request further
// the way you want, if you want
$this->_request->setControllerName( $someController );
$this->_request->setActionName( $someAction );
$this->setLayout( $someLayout );
}
}
}
/**
* Set up layout
*/
public function setLayout( $layout )
{
$layout = Zend_Layout::getMvcInstance();
$layout->setLayout( $layout );
}
}
And the My_Controller_Plugin_Abstract, which is not an actual abstract and which your controller plugin extends,looks like this:
class My_Controller_Plugin_Abstract
{
protected $_request;
public function __construct($request)
{
$this->setRequest($request);
$this->init();
}
private function setRequest($request)
{
$this->_request = $request;
}
}
And in the end the front controller plugin itself, which decides which one of the specific front controller plugins you should execute.
require_once 'Zend/Controller/Plugin/Abstract.php';
require_once 'Zend/Locale.php';
require_once 'Zend/Translate.php';
class My_Controller_Plugin extends Zend_Controller_Plugin_Abstract
{
/**
* before dispatch set up module/controller/action
*
* #param Zend_Controller_Request_Abstract $request
*/
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
// Make sure you get something
if(is_null($this->_request->getModuleName())) $this->_request->setModuleName('web');
// You should use zend - to camelCase convertor when doing things like this
$zendFilter = new Zend_Filter_Word_SeparatorToCamelCase('-');
$pluginClass = 'My_Controller_Plugin_'
. $zendFilter->filter($this->_request->getModuleName());
// Check if it exists
if(!class_exists($pluginClass)) {
throw new Exception('The front controller plugin class "'
. $pluginClass. ' does not exist');
}
Check if it is written correctly
if(!in_array('My_Controller_Plugin_Interface', class_implements($pluginClass))) {
throw new Exception('The front controller plugin class "'
. $pluginClass.'" must implement My_Controller_Plugin_Interface');
}
// If all is well instantiate it , and you will call the construct of the
// quasi - abstract , which will then call the init method of your
// My_Plugin_Controller_Web :)
$specificController = new $pluginClass($this->_request);
}
}
If you have never done this, now is the time. :)
Also, to register your front controller plugin with the application, you should edit the frontController entry in your app configuration. I will give you a json example, i'm sure you can translate it to ini / xml / yaml if you need...
"frontController": {
"moduleDirectory": "APPLICATION_PATH/modules",
"defaultModule": "web",
"modules[]": "",
"layout": "layout",
"layoutPath": "APPLICATION_PATH/layouts/scripts",
// This is the part where you register it!
"plugins": {
"plugin": "My_Controller_Plugin"
}
This might be a tad confusing, feel free to ask for a more detailed explanation if you need it.

Drupal Module - Form in Block not applying template

Help me figure out why isn't my form getting styled a la sites/all/modules/pecapture/themes/pecapture-displayform.tpl.php
Here's my code:
/**
* Implementation of hook_theme()
*/
function pecapture_theme() {
$path = drupal_get_path('module', 'pecapture') . '/theme';
return array(
'pecapture_displayform' => array(
'arguments' => array('form' => NULL),
'template' => 'pecapture-displayform',
'path' => $path,
),
);
}
Basically this says that theme files are in the module/theme folder ($path)
There is a theme function pecapture_displayform($form = NULL), called using theme('pecapture_displayform', $form) where $form is a Drupal form array
There is a template file pecapture_displayform.tpl.php at $path
function pecapture_block($op = 'list', $delta = 0, $edit = array()) {
$block = array();
if ($op == "list") { // Generate listing of blocks from this module, for the admin/block page
$block[0]["info"] = t('Persistent E-mail Capture Form Block');
}
else /* if ($op == 'view') */ { // Generate our block content
$block['subject'] = ''; //'Persistent E-mail Capture Form';
$block['content'] = pecapture_displayForm();
}
return $block;
} // function pecapture_block
This says that when you are viewing the block, use the function pecapture_displayForm() to generate the contents. $block gets php print()ed
/**
* Callback for pecapture_theme
*/
function pecapture_displayform() {
return drupal_get_form('pecapture_blockform');
}
This says return the html formatted drupal form array (for output)
function pecapture_blockform(&$form_state) {
/* the form, standard ... */
This is the form contents, it's typical.
I've tried calling the theme function explicitly in pecapture_displayform:
return theme('pecapture_displayform', $form);
and
return theme('pecapture_displayform', drupal_get_form($form));
So why is the form not going through pecapture-displayform.tpl.php ?
There's two basic ways of creating themes from a module - using a theme function, or using a template. In both cases, you need to register the themes in the hook_theme function for your module (pecapture_theme). That part of your example looks right.
If you register a theme function, you then create the theme function, and call it theme_themename. If you register a template (like you did) you use an optional template_preprocess function and a template. Template_preprocess functions are called template_preprocess_themename and are passed, by reference, an array of variables to be then passed to the template. Also, you should never directly call a theme function. Always uses theme('themename', $args) to access a theme so that drupal can handle it correctly (allows overriding, and correct variable preprocessing).
So, first of all, it looks like you're trying to directly call a theming function that drupal doesn't recognize as theme function. Second, you're using a template, so you need a function called template_preprocess_pecapture_displayform(&$vars) if you want to process the form before sending it to the template. Also make sure your template is called pecapture-display.tpl.php so it matches exactly the name you supplied in hook_theme except for the extension.
Also, it looks like you're trying to theme a form. So, you'll need to tell drupal_get_form to use your theme by including $form['#theme'] = 'pecapture_displayform' in your form function. You can output individual form elements in your theme by calling drupal_render($form['element']), calling drupal_render($form) will render any remaining un-rendered elements (drupal keeps track so they won't be rendered twice).
See http://api.drupal.org/api/drupal/developer--topics--forms_api.html/6 for more information on theming forms.
As long as you've specified the theme in your form function you won't need to call it explicitly, so you should be able to do
$block['content'] = drupal_get_form('pecapture_blockform');
in your block hook.

Categories