<?php
// https://forum.nette.org/cs/27213-dependent-form-select-with-ajax-chyba-please-select-a-valid-option
// https://forum.nette.org/cs/32545-jak-na-vicekrokovy-formular#p207046
protected function createComponentSelectForm($name)
{
$firstItems = [
1 => 'First option 1',
2 => 'First option 2'
];
// Je důležité předávat formuláři $this a $name jinak by nefungovalo níže použité $firstSelect->getValue()
$form = new \Nette\Application\UI\Form($this, $name);
$firstSelect = $form->addSelect('first', 'First select:', $firstItems)
->setPrompt('Select');
$secondItems = [0 => 'Select from first'];
if ($firstSelect->getValue()) {
$secondItems = [
0 => 'Select',
1 => 'First option ' . $value . ' - second option 1',
2 => 'First option ' . $value . ' - second option 2'
];
}
$form->addSelect('second', 'Second select:')
->setItems($secondItems);
$form->addSubmit('send', 'Submit');
$form->onSuccess[] = [$this, 'processSelectForm'];
return $form;
}
<?php
return new Multiplier(function ($id) {
return new Multiplier(function ($id2) use ($id) {
});
});
services:
- Config
reCaptcha:
siteKey: @Config::getSiteKey()
secretKey: @Config::getSecretKey()
methodName: 'addReCaptcha' # optional
<?php
# https://forum.nette.org/cs/31783-mazanie-suboru-po-samotnej-akcii-stiahnut-subor#p202279
use Nette\Application\Responses\FileResponse;
use Nette\Http\IRequest;
use Nette\Http\IResponse;
final class DownloadAndDeleteFileResponse implements Nette\Application\IResponse
{
private $response;
public function __construct(FileResponse $response)
{
$this->response = $response;
}
public funcion send(IRequest $request, IResponse $response)
{
$this->response->send($request, $response);
unlink($this->response->getFile());
}
<?php
if ($form['submit']->isSubmittedBy()) {
// ...
}
or
if ($form->isSubmitted() === $form['submit']) {
// ...
}
or
public function validate($form)
{
if ($form->isSubmitted()->getName() == 'reloadSelect')
return;
}
<?php
namespace App\FrontModule\Components;
use App;
use Nette\Application\UI\Control;
use Nette\Caching\Cache;
use Nette\Caching\IStorage;
/**
* Class Youtube
*/
class Youtube extends FrontControl
{
public $presets;
public $content;
public $cacheStorage;
public function __construct(App\Model\Presets $presets, IStorage $IStorage)
{
$this->presets = $presets;
$this->cacheStorage = $IStorage;
}
private function fetchData()
{
$user = $this->presets->defaults['keys']['youtube']['user'];
$path = "https://www.youtube.com/feeds/videos.xml?channel_id=$user";
try {
$out = json_decode(json_encode(@new \SimpleXMLIterator($path, null, true)), TRUE);
return $out;
} catch (\Exception $e) {
return false;
}
}
public function getData()
{
$cache = new Cache($this->cacheStorage, 'youtubePosts');
try {
$out = $cache->load("videos");
} catch (\Exception $e) {
$out = false;
}
if (empty($out)) {
try {
$data = self::fetchData();
if ($data) {
$out = $data['entry'];
$cache->save("videos", $out, array(
Cache::EXPIRATION => '+30 minutes',
Cache::SLIDING => TRUE
));
} else {
$out = false;
}
} catch (\Exception $e) {
$out = false;
}
}
return $out;
}
public function renderDefault(array $config = array())
{
$config = $this->getCurrentConfig($config);
$this->template->presets = $this->presets->getPresets();
$this->template->youtubeData = $this->getData();
$this->render($config);
}
}
<?php
namespace App\FrontModule\Components;
use App;
use Nette\Caching\Cache;
use Nette\Caching\IStorage;
use Nette\Utils\Json;
/**
* Class Instagram
*/
class Instagram extends FrontControl
{
public $presets;
public $content;
public $cacheStorage;
public function __construct(App\Model\Presets $presets, IStorage $IStorage)
{
$this->presets = $presets;
$this->cacheStorage = $IStorage;
}
private function fetchData()
{
$token = $this->presets->defaults['keys']['instagram']['token'];
$user = $this->presets->defaults['keys']['instagram']['user'];
$url = "https://api.instagram.com/v1/users/$user/media/recent/?access_token=$token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 20);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
public function getData()
{
$cache = new Cache($this->cacheStorage, 'instagramPosts');
try {
$out = $cache->load("photos");
} catch (\Exception $e) {
$out = false;
}
if (empty($out)) {
try {
$data = self::fetchData();
$out = Json::decode($data, true);
$out = $out['data'];
$cache->save("photos", $out, array(
Cache::EXPIRATION => '+30 minutes',
Cache::SLIDING => TRUE
));
} catch (\Exception $e) {
$out = false;
}
}
return $out;
}
public function renderDefault(array $config = array())
{
$config = $this->getCurrentConfig($config);
$this->template->presets = $this->presets->getPresets();
$this->template->instagramData = $this->getData();
$this->render($config);
}
}
{
"block": { "prefix": "block", "body": "{block ${1:content}}\n$0\n{/block}" },
"snippet": { "prefix": "snippet", "body": "{snippet ${1:content}}\n$0\n{/snippet}" },
"layout": { "prefix": "layout", "body": "{layout '${1:../@layout.latte}'}\n$0" },
"extends": { "prefix": "extends", "body": "{extends '${1:../@layout.latte}'}\n$0" },
"capture": { "prefix": "capture", "body": "{capture \\$${1:var}}\n$0\n{/capture}" },
"define": { "prefix": "define", "body": "{define ${1:content}}\n$0\n{/define}" },
"include": { "prefix": "include", "body": "{include #${1:content}}\n$0" },
"includeblock": { "prefix": "includeblock", "body": "{includeblock '${1:file.latte}'}\n$0" },
"foreach": { "prefix": "foreach", "body": "{foreach \\$$1s as \\$$1}\n$0\n{/foreach}" },
"while": { "prefix": "while", "body": "{while \\$$1 = \\$$1s->fetch()}\n$0\n{/while}" },
"for": { "prefix": "for", "body": "{for \\$${1:i} = 0; \\$${1:i} < ${2:10}; \\$${1:i}++}\n$0\n{/for}" },
"first": { "prefix": "first", "body": "{first}\n$0\n{/first}" },
"last": { "prefix": "last", "body": "{last}\n$0\n{/last}" },
"sep": { "prefix": "sep", "body": "{sep}\n$0\n{/sep}" },
"continueIf": { "prefix": "continueIf", "body": "{continueIf \\$${1:foo}}$0" },
"breakIf": { "prefix": "breakIf", "body": "{breakIf \\$${1:foo}}$0" },
"if": { "prefix": "if", "body": "{if \\$${1:foo}}\n$0\n{/if}" },
"ifset": { "prefix": "ifset", "body": "{ifset \\$${1:foo}}\n$0\n{/ifset}" },
"cache": { "prefix": "cache", "body": "{cache \\$${1:var}}\n$0\n{/cache}" },
"default": { "prefix": "default", "body": "{default \\$${1:foo = ''}}$0" },
"link": { "prefix": "link", "body": "{link ${1:Default}}\n$0" },
"plink": { "prefix": "plink", "body": "{plink ${1:Default}}\n$0" },
"control": { "prefix": "control", "body": "{control ${1:foo}}\n$0" },
"form": { "prefix": "form", "body": "{form ${1:foo}}\n$0\n{/form}" },
"label": { "prefix": "label", "body": "{label ${1:foo} /}\n" },
"input": { "prefix": "input", "body": "{input ${1:foo}}\n$0" },
"syntax": { "prefix": "syntax", "body": "{syntax ${1:mode}}\n$0\n{/syntax}" },
"l": { "prefix": "l", "body": "{l}$0" },
"r": { "prefix": "r", "body": "{r}$0" },
"contentType": { "prefix": "contentType", "body": "{contentType ${1:application/xml}}\n$0" },
"status": { "prefix": "status", "body": "{status ${1:500}}\n$0" },
"dump": { "prefix": "dump", "body": "{dump \\$${1:var}}\n$0" },
"debugbreak": { "prefix": "debugbreak", "body": "{debugbreak \\$${1:cond}}\n$0" },
// Default Helpers
// String modification
"|truncate": { "prefix": "|truncate", "body": "|truncate:${1:length}${2:,'${3:append}'}" },
"|substr": { "prefix": "|substr", "body": "|substr:${1:offset}${2:,${3:length}}" },
"|trim": { "prefix": "|trim", "body": "|trim${1::'${2:charset}'}" },
"|webalize": { "prefix": "|webalize", "body": "|webalize${1::'${2:charlist}'${3:,${4:lower}}}" },
"|indent": { "prefix": "|indent", "body": "|indent${1::${2:level}${3:,'${4:char}'}}" },
"|replace": { "prefix": "|replace", "body": "|replace:'${1:search}'${2:,'${3:replace}'}" },
"|replaceRE": { "prefix": "|replaceRE", "body": "|replaceRE:'${1:pattern}'${2:,'${3:replace}'}" },
"|padLeft": { "prefix": "|padLeft", "body": "|padLeft:${1:length}${2:,'${3:pad}'}" },
"|padRight": { "prefix": "|padRight", "body": "|padRight:${1:length}${2:,'${3:pad}'}" },
"|repeat": { "prefix": "|repeat", "body": "|repeat:${1:count}" },
"|implode": { "prefix": "|implode", "body": "|implode:'${1:glue}'" },
// Formatting
"|date": { "prefix": "|date", "body": "|date:'${1:format}'" },
"|number": { "prefix": "|number", "body": "|number${1::${2:decimals}${3:,'${4:decPoint}'${5:,'${6:thousandsSep}'}}}" },
"|bytes": { "prefix": "|bytes", "body": "|bytes${1::${2:precision}}" },
}
{define form $formName}
<form n:name=$formName>
<ul class=error n:ifcontent>
<li n:foreach="$form->ownErrors as $error">{$error}</li>
</ul>
<table>
<tr n:foreach="$form->controls as $input"
n:if="!$input->getOption(rendered) && $input->getOption(type) !== hidden"
n:class="$input->required ? required">
<th>{label $input}</th>
<td>{input $input} <span class=error n:ifcontent>{$input->error}</span></td>
</tr>
</table>
</form>
{/define}
{* for Bootstrap v3 *}
{define bootstrap-form $formName}
<form n:name=$formName class=form-horizontal>
<ul class=error n:ifcontent>
<li n:foreach="$form->ownErrors as $error">{$error}</li>
</ul>
<div n:foreach="$form->controls as $name => $input"
n:if="!$input->getOption(rendered) && $input->getOption(type) !== hidden"
n:class="form-group, $input->required ? required, $input->error ? has-error">
<div class="col-sm-2 control-label">{label $input}</div>
<div class="col-sm-10">
{if $input->getOption(type) in [text, select, textarea]}
{input $input class => form-control}
{elseif $input->getOption(type) === button}
{input $input class => "btn btn-default"}
{elseif $input->getOption(type) === checkbox}
<div class="checkbox">{input $input}</div>
{elseif $input->getOption(type) === radio}
<div class="radio">{input $input}</div>
{else}
{input $input}
{/if}
<span class=help-block n:ifcontent>{$input->error ?: $input->getOption(description)}</span>
</div>
</div>
</form>
{/define}
<?php
namespace Model;
use Nette;
class DemandStorage extends Nette\Object
{
protected $session;
public function __construct(Nette\Http\Session $session)
{
$this->session = $session->getSection('demandForm');
}
public function flush()
{
$this->session->remove();
}
public function getRawData()
{
return isset($this->session['formData']) ? $this->session['formData'] : array();
}
public function getStepNumber()
{
return isset($this->session['step']) ? $this->session['step'] : 1;
}
public function setRawData($data)
{
$this->session['formData'] = $data;
return $this;
}
public function addRawData($data)
{
$originalData = $this->getRawData();
$data = array_merge($originalData, $data);
$this->setRawData($data);
return $this;
}
public function setStepNumber($step = 1)
{
$this->session['step'] = $step;
return $this;
}
public function getValue($name, $default = NULL)
{
$data = $this->getRawData();
return Nette\Utils\Arrays::get($data, $name, $default);
}
public function setValue($name, $value)
{
$data = $this->getRawData();
$data[$name] = $value;
$this->setRawData($data);
return $this;
}
public function unsetValue($name)
{
$data = $this->getRawData();
if(isset($data[$name]))
unset($data[$name]);
$this->setRawData($data);
return $this;
}
public function issetValue($name)
{
$data = $this->getRawData();
return isset($data[$name]);
}
}