Utworzenie wirtualnego hosta /etc/apache2/sites-available/000-default.conf
<VirtualHost 81.137.4.24:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html/example ServerName example.pl </VirtualHost>
Utworzenie wirtualnego hosta /etc/apache2/sites-available/000-default.conf
<VirtualHost 81.137.4.24:80> ServerAdmin webmaster@localhost DocumentRoot /var/www/html/example ServerName example.pl </VirtualHost>
Można dodać/usunąć domenę do certyfikatu już istniejącego np. o nazwie example.com:
# certbot certonly --cert-name example.com -d example.org,www.example.org
Nowy certyfikat będzie zawierał teraz dwie nazwy example.org oraz www.example.org
# apt install ca-certificates apt-transport-https
https://certbot.eff.org/docs/using.html
# certbot certonly --webroot -w /var/www/rewita/webroot -d tmp.rewita.pl -d crm.rewita.pl
Odnowienie co 60 dni poprzez moduł wykorzystujący crona
Odnawia wszystkie certyfikaty, które zbliżają się do wygaśnięcia <= 30 dni do końca. Komendę można wydawać codziennie lub raz na tydzień, można dodać do crona.
# certbot renew
Tylko sprawdza działania –dry-run
# certbot renew --dry-run
Zmiana długości klucza z 2048 na 4096
# certbot renew --rsa-key-size 4096
DNS plugin musi być zainstalowany dla dostawcy dns
# certbot -a <dns-plugin> -i apache -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory
Ręczna konfiguracja certyfikatów:
# certbot certonly --authenticator standalone
Przed zainstalowaniem trzeba zatrzymać serwer ręcznie lub za pomocą skryptów:
# certbot certonly --authenticator standalone --pre-hook "apache2ctl -k stop" --post-hook "apache2ctl -k start"
https://certbot.eff.org/lets-encrypt/debianstretch-apache
# apt-get install python-certbot-apache -t stretch-backports
# certbot --authenticator webroot --installer apache
app.php w sekcji Log => [
'auth' => [ 'className' => 'Cake\Log\Engine\FileLog', 'path' => LOGS, 'file' => 'auth', 'url' => env('LOG_AUTH_URL', null), 'scopes' => ['auth'], ],
.htaccess – 14 dni czas sesji
php_value session.gc_maxlifetime 1209600
https://github.com/servocoder/RichFilemanager/wiki/Configuration-options
Instalacja projektu w katalogu filemanager
# composer create-project --prefer-dist servocoder/richfilemanager filemanager
# chown -R www-data.www-data filemanager/userdata
– ustawienie virtualnego serwera np. https://mymanager.pl
– dostęp poprzez podany URL
Zmiana userfiles na media
# nano filemanager/connectors/php/filemanager.php
$local->setRoot('media', true, true);
Dostęp do pliku
https://mymanager.pl/media/dir/file.png
# apt-get -y install ifupdown resolvconf # ifconfig
Obecna konfiguracja DHCP
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.6 netmask 255.255.255.0 broadcast 192.168.1.255
# nano /etc/network/interfaces
Master
nano /etc/bind/named.conf.local
https://www.itzgeek.com/debian/configure-dns-server-on-debian-9.html
Instalacja bind9
# apt-get install -y bind9 bind9utils bind9-doc dnsutils
Globalna konfiguracja
# cd /etc/bind/ # less named.conf - nie zmieniany # nano named.conf.local - plik do edycji
https://wkhtmltopdf.org
https://github.com/FriendsOfCake/CakePdf
Pobrać plik instalacyjny silnika ze strony i zainstalować
# dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb
Podlinkować do domyślnej lokalizacji
# ln -s /usr/local/bin/wkhtmltopdf /usr/bin/wkhtmltopdf
use Cake\Database\Expression\QueryExpression; ... function incrementCounters() { $expression = new QueryExpression('view_count=view_count +1'); $this->updateAll([$expression], ['published' => true]); }
// In src/Model/Table/OrdersTable.php public function buildRules(RulesChecker $rules) { $check = function($order) { if($order->shipping_mode !== 'free') { return true; } return $order->price >= 100; }; $rules->add($check, [ 'errorField' => 'shipping_mode' , 'message' => 'Nie ma bezpłatnej dostawy poniżej 100zł' ]); return $rules; } // W kontrolerze $order->price = 50; $order->shipping_mode = 'free' ; $ordersTable->save($order); // Returns false
// In src/Model/Table/UsersTable.php public function validatePasswords($validator) { $validator->add('password2', 'no-misspelling' , [ 'rule' => [ 'compareWith' , 'password' ], 'message' => 'Hasła nie są takie same.' , ]); ... return $validator; }
Dołączenie modeli do pobranego już zasobu
$articles = $this->Articles->find()->all(); $withMore = $this->Articles->loadInto($articles, ['Comments', 'Users']);
Plik konfiguracyjny tinyMce
Przechowuje w tabeli ilość rekordów podrzędnych (dzieci). Definiowany jest na tabeli podrzędnej ( belongsTo() ). Tabela nadrzędna musi mieć kolumnę typu int (np. comment_count)
class CommentsTable extends Table
{
public function initialize(array $config)
{
$this->belongsTo('Articles');
$this->addBehavior('CounterCache' , [
'Articles' => [ 'comment_count' ]
]);
}
}
Można zastosować CounterCache w powiązaniach belongsToMany() tylko z opcją through. Wówczas behaviour definiuje się w tabeli łączącej gdyż posiada powiązania belongsTo().
Wprowadzenie warunku – zlicza tylko komentarze bez spamu
$this->addBehavior('CounterCache' , [
'Articles' => [
'comment_count' => [
'conditions' => [ 'Comments.spam' => false]
]
]
]);
Obsługuje złożone struktury hierarchiczne. Zapewnia wiele metod dostępu, prezentacji, generowania list, ścieżek i manipulacji elementami.
Kolumny wymagane w tabeli
parent_id lft rght level - przechowuje poziom (opcjonalna) model - lub country własna kolumna dla opcji skope (opcjonalna)
Izolowanie procesorów renderowania stron – bezpieczeństwo
chrome://flags Strict site isolation Site isolation trial opt-out
chrome://flags/#enable-site-per-process
class ArticlesTable extends Table
{
public function initialize(array $config)
{
$this->setDisplayField('title');
}
}
$query = $articles->find('list' , [ 'keyField' => 'slug' , 'valueField' => 'title' 'groupField' => 'author_id' ]); $data = $query->toArray();
$query = $articles->find('list' , [
'keyField' => 'id' ,
'valueField' => 'author.name'
])->contain([ 'Authors' ]);
$query->enableHydration(false);
Dostępne do zmiany przez formularz
class User extends Entity
{
protected $_accessible = [
'id' => false,
'*' => true
]
}
$article->accessible('title' , false); $article->set($properties, [ 'guard' => false]);
Właściwości wirtualne uwzgl. w konwersji na array/json
class User extends Entity
{
protected $_virtual = [ 'full_name' ];
}
$user->virtualProperties([ 'full_name' , 'is_admin' ]);
Nie będą exportowane do formatu array/json
class User extends Entity
{
protected $_hidden = [ 'password' ];
}
$user->hiddenProperties([ 'password' , 'recovery_question' ]);
$article->has('title' ); // czy jest i czy ma wartość $article->isEmpty('title' ); // czy jest pusta $article->hasValue('title' ); // czy ma wartość $article->isNew(); // nie zapisany jeszcze w bazie $article->isDirty('title' ); // czy zmieniono title $article->comments[] = $newComment; $article->setDirty('comments' , true); // ustaw - zmieniono $dirtyFields = $entity->getDirty(); // pobierz wszystkie falgi $article->clean(); // wyczyść wszystkie flagi dirty
$entity->unsetProperty('name');
$user->unsetProperty('beers'); // user belongsToMany beers
$user->has('beers'); // false
// Aby znowu mieć dostęp - ładujemy ręcznie
$user= $this->Programmers->loadInto($user, ['Beers']);
Definiowanie właściwości wirtualnej (nie będzie zapisana do bazy)
protected function _getFullName() { return $this->_properties[ 'first_name' ] . ' ' . $this->_properties[ 'last_name' ]; }
echo $user->full_name;
Cake – korzystanie z drugiej bazy danych
namespace App\Model\Table;
use Cake\ORM\Table;
class ArticlesTable extends Table
{
public static function defaultConnectionName() {
return 'replica_db' ;
}
}
$user['age'] = $user['birth_date']->diff(new \DateTime)->y;