Skip to content

Ниже приведен пример как можно сделать рекурсивный chmod в каталоге с большой вложенностью.

Так, чтобы для папок ставились одни права, а для для файлов другие.

1. Переходим в нужный каталог.
2. И выполняем следующую команду для установки прав на файлы (вместо 644 – разумеется нужные права).

find . -type f -exec chmod 644 {} \;

 
3. Затем следующую команду для установки прав на каталоги (где вместо 755 опять таки нужные права доступа).

find . -type d -exec chmod 755 {} \;

 

Имеем следующую конструкцию:

Контейнер component_left_row зависит от высоты контейнера component_right_row, потому что обычно он самый большой по высоте. Но если контейнер component_left_row_userinfo становится больше чем component_right_row - то внизу component_right_row образуется пустота и выглядывает фон.
Нужно чтобы component_right_row растянулся,а сам он не хочет)

Выход - джаваскрипт.

$(document).ready(function(){
var height_left = document.getElementById('component_left_row_userinfo').clientHeight; //узнаем высоту левого дива
var height_right = document.getElementById('component_right_row').clientHeight; //узнаем высоту правого дива

if (height_right//если меньше - делаем)
$("#component_right_row").css({height:$("#component_left_row_userinfo").height()}); //аяксовая магия
$("#component_right_row").animate({height:$("#component_left_row_userinfo").height()},600); //аяксовая магия
}
});

Понадобилось при генерации форм распознавать, что же ввел пользователь, и в зависимости от этого пихать рядом со ссылочкой фавикон сайта. Ну и название ссылки чтобы генерилось нормальное.

 

Вот функция:

...continue reading "Функция генерации ссылки и картинки к ней, в зависимости от введенного URL"

Назрела необходимость удалять несколько сообщений одновременно.
Три дня изысков и вуаля - чекбоксы,массив данных-и можно удалять отмеченные сообщения.
Код под спойлером.
В Instant CMS подобный код называется хаком. Так что я теперь официально хакер =)

 

Это пихаем в темплейт:

<td width=30px><input name="checkbox[]" type="checkbox" id="checkbox[]" value="{$record.id}"></td>

checkbox[] - название массива. В скобки ничего не пихаем, ибо php тогда не поймет что ему передают массив.

<form action="/users/delselectedmsg.html" id="selmessage" method="POST" name="selmessage">

Это будет форма, в которой выводятся месседжи.

<a href="javascript:document.selmessage.submit();">Удалить отмеченные</a>

Это волшебная кнопочка =)

Это пихаем во фронтенд:

if ($do=='delselected'){

if (!$cfg['sw_msg']) { cmsCore::error404(); }
if (!$inUser->id) { cmsCore::error404(); }

// Удалить сразу несколько записей можно
// при помощи запроса "DELETE FROM table_1 WHERE id IN (1,3,5,7)"
// Получаем список отмеченных checkbox
$type = $_POST["checkbox"];
if(!empty($type))
{
// Начинаем формировать переменную, содержащую этот список
// в формате "(3,5,6,7)"

foreach($type as $val) $query.= "$val,";
// Удаляем последнюю запятую, заменяя ее закрывающей скобкой)
$query = substr($query, 0, strlen($query) - 1 );
// Завершаем формирование SQL-запроса на удаление
//$query = "DELETE FROM table_1 WHERE id IN ".$query;

$msg = $inDB->get_fields('cms_user_msg', "id IN ($query)", '*');

if ($msg['to_id']==$inUser->id){
$inDB->query("UPDATE cms_user_msg SET to_del=1 WHERE id IN ($query)");
$inCore->addSessionMessage($_LANG['MESS_DEL_OK'], 'info');
}

if ($msg['from_id']==$inUser->id && !$msg['is_new']){
$inDB->query("UPDATE cms_user_msg SET from_del=1 WHERE id IN ($query)");
$inCore->addSessionMessage($_LANG['MESS_DEL_OK'], 'info');
}

if ($msg['from_id']==$inUser->id && $msg['is_new']){
$inDB->query("DELETE FROM cms_user_msg WHERE id IN ($query) LIMIT 1");
$inCore->addSessionMessage($_LANG['MESS_BACK_OK'], 'info');
}

$inDB->query("DELETE FROM cms_user_msg WHERE to_del=1 AND from_del=1");

$inCore->redirectBack();

}
else
$inCore->redirectBack();

}

Это - в роутер:

$routes[] = array(
'_uri' => '/^users\/delselectedmsg.html$/i',
'do' => 'delselected',
1 => 'id'
);

Еще у одного чувака спиздил классный аяксовый аккордеон, но тут выкладывать не буду, ибо лень.

Пользуясь случаем, скопипастю у бывшего сенсея инфу о том, как запустить vnc сервер, а то у меня это не получалось другими способами.

Create passwd:
x11vnc -storepasswd

GDM:
x11vnc -forever -bg -rfbauth /root/.vnc/passwd -display :0 -auth /var/lib/gdm/:0.Xauth

SLIM:
x11vnc -forever -bg -rfbauth /root/.vnc/passwd -display :0 -auth /var/run/slim.auth

Кстати подключаться к нему легче всего - юзая remmina, она позволяет сохранить профиль подключения, чтобы потом в пару кликов подключиться снова. Пускать vnc через туннель она также умеет. И еще умеет RDP. И много всего-всего.

Cacti отказался рисовать графики. В логах всё ок. Понятно что ничего не понятно. А к слову, часы недавно сбились (загрузился в винду и она решила синкнуть время). А я про это как-то забыл.

Попытки запустить поллер вручную с просмотром дебага показала что скрипт запускался -9490 секунд назад (отрицательное время, поскольку время последнего запуска скрипта - в будущем ):

root@cacti:/var/www/default/cacti# php /var/www/default/cacti/poller.php -d
05/01/2012 07:36:54 AM - POLLER: Poller[0] NOTE: Poller Int: '300', Cron Int: '300', Time Since Last: '-9490', Max Runtime '298', Poller Runs: '1'

Тут и вспомнил что только буквально недавно синкал время из-за того что оно было неправильным (до синхронизации время было на три часа больше)

Для того чтобы скрипт запустился - надо в нём переменную $force объявить TRUE, запустить его снова, и вернуть значение переменной обратно на FALSE.

Но после этого столкнулся на такие сообщения:

ERROR: /var/www/default/cacti/rra/26/258.rrd: illegal attempt to update using time 1335858285 when last update time is 1335867065 (minimum one second step)

Это потому что в файлах round robin database последнее время также в будущем. А RRD не даст задним числом обновиться базам. Так что не паримся и ждем пока время станет больше времени обновления rrd.
Поллер уже запускается, так что кактус сам начнет рисовать графики, пинать его не нужно.

π