<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WebGuruz</title>
	<atom:link href="http://webguruz.ru/feed/" rel="self" type="application/rss+xml" />
	<link>http://webguruz.ru</link>
	<description>web разработка, web-программирование, ubuntu linux, компьютеры, инернет, безопасность</description>
	<lastBuildDate>Wed, 10 Sep 2014 04:58:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Замена иконки Skype в Ubuntu</title>
		<link>http://webguruz.ru/ubuntu/%d0%b7%d0%b0%d0%bc%d0%b5%d0%bd%d0%b0-%d0%b8%d0%ba%d0%be%d0%bd%d0%ba%d0%b8-skype-%d0%b2-ubuntu/</link>
		<comments>http://webguruz.ru/ubuntu/%d0%b7%d0%b0%d0%bc%d0%b5%d0%bd%d0%b0-%d0%b8%d0%ba%d0%be%d0%bd%d0%ba%d0%b8-skype-%d0%b2-ubuntu/#comments</comments>
		<pubDate>Tue, 17 Jun 2014 16:55:45 +0000</pubDate>
		<dc:creator>dimaz</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[skype]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1174</guid>
		<description><![CDATA[Иконка скайпа всегда выделялась в панели индикаторов, что очень сильно раздражало. И вот, вроде бы, уже привык к этому, но нашлось отличное решение проблемы, а именно подправить sni-qt, который и отвечает за вывод иконок трея Qt приложений в панели индикаторов unity. Конечно можно, используя skype wrapper, иконку засунуть в indicator-messages, но мне удобней, чтобы иконка [...]]]></description>
			<content:encoded><![CDATA[<p>Иконка скайпа всегда выделялась в панели индикаторов, что очень сильно раздражало. И вот, вроде бы, уже привык к этому, но нашлось отличное решение проблемы, а именно подправить sni-qt, который и отвечает за вывод иконок трея Qt приложений в панели индикаторов unity.<br />
Конечно можно, используя skype wrapper, иконку засунуть в indicator-messages, но мне удобней, чтобы иконка была сразу на панели.<br />
<span id="more-1174"></span><br />
Скатываем исходники sni-qt:</p>
<pre class="brush: bash; title: ; notranslate">apt-get source sni-qt &amp;&amp; cd sni-qt*</pre>
<p>Находим файл iconcache.cpp и заменяем один метод:</p>
<pre class="brush: csharp; title: ; notranslate">void IconCache::cacheIcon(const QString&amp; key, const QIcon&amp; icon) const {
    QList&lt;QSize&gt; sizes = icon.availableSizes();
    if (sizes.isEmpty()) {
        sizes &lt;&lt; QSize(16,16) &lt;&lt; QSize(22,22) &lt;&lt; QSize(32,32) &lt;&lt; QSize(48,48);
    }
    QDir dir(m_themePath);
    Q_FOREACH(const QSize&amp; size, sizes) {
        QPixmap pix = icon.pixmap(size);
        QString dirName = QString(&quot;hicolor/%1x%1/apps&quot;).arg(size.width());
        if (!dir.exists(dirName)) {
            if (!dir.mkpath(dirName)) {
                qWarning(&quot;Could not create '%s' dir in '%s'&quot;,
                    qPrintable(m_themePath), qPrintable(dirName));
                continue;
            }
        }
        QString pixPath = QString(&quot;%1/%2/%3.png&quot;).arg(m_themePath).arg(dirName).arg(key);
        bool replaced = false;
        // Если skype выполняем
        if (QString::compare(QCoreApplication::applicationFilePath().section('/', -1), &quot;skype&quot;) == 0) {
            QString iconFile;
            QString hash = QString(key);
            hash.remove(0, hash.lastIndexOf(&quot;_&quot;)+1);
            // Сопоставляем хэшу изображения необходимого файла иконки
            if (QString::compare(&quot;37e170fc54e7355d9d298917e74f9ea9&quot;, hash) == 0) { // в сети
                iconFile = &quot;skype_online.svg&quot;;
            } else
            if (QString::compare(&quot;602c84fa0f4d61c64f770495a500279e&quot;, hash) == 0) { // нет на месте
                iconFile = &quot;skype_away.svg&quot;;
            } else
            if (QString::compare(&quot;bd2e3972c2a97520bbabac7e275d7b9f&quot;, hash) == 0) { // не беспокоить
                iconFile = &quot;skype_busy.svg&quot;;
            } else
            if (QString::compare(&quot;2d1ee5482260fd9cd180b32787792683&quot;, hash) == 0) { // не в сети
                iconFile = &quot;skype_offline.svg&quot;;
            } else
            if (QString::compare(&quot;ad07f7e1479ab81315ec8c6c23e19170&quot;, hash) == 0) { // невидимый
                iconFile = &quot;skype_invisible.svg&quot;;
            } else
            if (QString::compare(&quot;f2fc4a539a7b9553f5b35241d1154e84&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.svg&quot;;
            } else
            if (QString::compare(&quot;dad77418071bead905e2dbe605715dcd&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.svg&quot;;
            } else
            if (QString::compare(&quot;6cbeda8e2c9f56d3ac75ccdf8d282a69&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.svg&quot;;
            } else
            if (QString::compare(&quot;0972e5fde53a4a87346ebb91c4c2b159&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.svg&quot;;
            }
            else { // уведомления, пропущенные звонки, непрочитанные сообщения
                iconFile = &quot;skype_message.svg&quot;;
            }
            // Загружает и сохраняет в временном каталоге подменяемую иконку
            iconFile = QString(&quot;/usr/share/icons/skype/%1&quot;).arg(iconFile);
            QIcon newIcon = QIcon(iconFile);
            if (!newIcon.isNull()) {
                QList&lt;QSize&gt; newSizes = newIcon.availableSizes();
                if (newSizes.isEmpty()) {
                    newSizes &lt;&lt; QSize(22, 22);
                }
                Q_FOREACH(const QSize&amp; newSize, newSizes) {
                    if (newSize.width() == 22) {
                        QPixmap newPix = newIcon.pixmap(newSize);
                        replaced = newPix.save(pixPath, &quot;png&quot;);
                        break;
                    }
                }
            }
        }

        if (!replaced) {
            if (!pix.save(pixPath, &quot;png&quot;)) {
                qWarning(&quot;Could not save icon as '%s'&quot;, qPrintable(pixPath));
            }
        }
    }
    m_cacheKeys &lt;&lt; key;
    QFileInfo info(m_themePath);
    QDateTime mtime = info.lastModified();
    FsUtils::touch(m_themePath, mtime.addSecs(1));
}</pre>
<p>Собираем и устанавливаем</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get build-dep sni-qt
mkdir build &amp;&amp; cmake --build=build .
make &amp;&amp; sudo make install</pre>
<p>Как видно иконки будут браться из директории:</p>
<pre class="brush: bash; title: ; notranslate">/usr/share/icons/skype</pre>
<p>Иконки должны быть векторными. Можно использовать системные от empathy, только нужно будет дать им правильные названия или изменить в коде на нужные.</p>
<p>Есть один небольшой минус, на иконке не будет отображатся количество чатов с непрочитанными сообщениями, но это можно пережить.</p>
<p><strong>UPD:</strong> существует проблема в 64 битных версиях. По непонятной причине библиотека отказывается конвертить из svg в png. Поступим просто, будем использовать png, но при изменении размера панели, придется иконки перерисовывать. Такое случается не часто, так что это не критично.</p>
<pre class="brush: csharp; title: ; notranslate">
IconCache::IconCache(const QString&amp; baseDir, QObject* parent)
: QObject(parent)
, m_themePath(baseDir + &quot;/icons&quot;)
{
    QDir dir(baseDir);
    bool ok = dir.mkdir(&quot;icons&quot;);
    if (!ok) {
        qCritical(&quot;Could not create '%s' dir for SNI icon cache&quot;, qPrintable(m_themePath));
        m_themePath = QString();
        return;
    }
}

QString IconCache::themePath() const
{
    return m_themePath;
}

QString IconCache::nameForIcon(const QIcon&amp; icon) const
{
    if (icon.isNull()) {
        return QString();
    }

    QString key = computeKeyForIcon(icon);
    QStringList::iterator it = qFind(m_cacheKeys.begin(), m_cacheKeys.end(), key);
    if (it == m_cacheKeys.end()) {
        cacheIcon(key, icon);
        trimCache();
    } else {
        // Place key at the end of list as it is the most recently accessed
        m_cacheKeys.erase(it);
        m_cacheKeys.append(key);
    }

    return key;
}

void IconCache::trimCache() const
{
    QDir dir(m_themePath + &quot;/hicolor&quot;);
    dir.setFilter(QDir::Dirs);

    while (m_cacheKeys.count() &gt; MaxIconCount) {
        QString cacheKey = m_cacheKeys.takeFirst();

        Q_FOREACH(const QString&amp; sizeDir, dir.entryList()) {
            QString iconSubPath = QString(&quot;%1/apps/%2.png&quot;).arg(sizeDir).arg(cacheKey);
            if (dir.exists(iconSubPath)) {
                dir.remove(iconSubPath);
            }
        }
    }
}

void IconCache::cacheIcon(const QString&amp; key, const QIcon&amp; icon) const {
    QList&lt;QSize&gt; sizes = icon.availableSizes();
    if (sizes.isEmpty()) {
        sizes &lt;&lt; QSize(16,16) &lt;&lt; QSize(22,22) &lt;&lt; QSize(32,32) &lt;&lt; QSize(48,48);
    }
    QDir dir(m_themePath);
    Q_FOREACH(const QSize&amp; size, sizes) {
        QPixmap pix = icon.pixmap(size);
        QString dirName = QString(&quot;hicolor/%1x%1/apps&quot;).arg(size.width());
        if (!dir.exists(dirName)) {
            if (!dir.mkpath(dirName)) {
                qWarning(&quot;Could not create '%s' dir in '%s'&quot;,
                    qPrintable(m_themePath), qPrintable(dirName));
                continue;
            }
        }
        QString pixPath = QString(&quot;%1/%2/%3.png&quot;).arg(m_themePath).arg(dirName).arg(key);
        bool replaced = false;
        // Если skype выполняем
        if (QString::compare(QCoreApplication::applicationFilePath().section('/', -1), &quot;skype&quot;) == 0) {
            QString iconFile;
            QString hash = QString(key);
            hash.remove(0, hash.lastIndexOf(&quot;_&quot;)+1);

            // Сопоставляем хэшу изображения необходимого файла иконки
            if (QString::compare(&quot;37e170fc54e7355d9d298917e74f9ea9&quot;, hash) == 0) { // в сети
                iconFile = &quot;skype_online.png&quot;;
            } else
            if (QString::compare(&quot;602c84fa0f4d61c64f770495a500279e&quot;, hash) == 0) { // нет на месте
                iconFile = &quot;skype_away.png&quot;;
            } else
            if (QString::compare(&quot;bd2e3972c2a97520bbabac7e275d7b9f&quot;, hash) == 0) { // не беспокоить
                iconFile = &quot;skype_busy.png&quot;;
            } else
            if (QString::compare(&quot;2d1ee5482260fd9cd180b32787792683&quot;, hash) == 0) { // не в сети
                iconFile = &quot;skype_offline.png&quot;;
            } else
            if (QString::compare(&quot;ad07f7e1479ab81315ec8c6c23e19170&quot;, hash) == 0) { // невидимый
                iconFile = &quot;skype_invisible.png&quot;;
            } else
            if (QString::compare(&quot;f2fc4a539a7b9553f5b35241d1154e84&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.png&quot;;
            } else
            if (QString::compare(&quot;dad77418071bead905e2dbe605715dcd&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.png&quot;;
            } else
            if (QString::compare(&quot;6cbeda8e2c9f56d3ac75ccdf8d282a69&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.png&quot;;
            } else
            if (QString::compare(&quot;0972e5fde53a4a87346ebb91c4c2b159&quot;, hash) == 0) { // загрузка
                iconFile = &quot;skype_load.png&quot;;
            }
            else { // уведомления, пропущенные звонки, непрочитанные сообщения
                iconFile = &quot;skype_message.png&quot;;
            }
            // Загружает и сохраняет в временном каталоге подменяемую иконку
            iconFile = QString(&quot;/usr/share/pixmaps/skype/%1&quot;).arg(iconFile);

            QFile file(iconFile);
						if (QFile::exists(pixPath)) {
							replaced = true;
						} else if (file.exists()) {
							QFile::copy(iconFile, pixPath);
              replaced = true;
						}

        }

        if (!replaced) {
            if (!pix.save(pixPath, &quot;png&quot;)) {
              qWarning(&quot;Could not save icon as '%s'&quot;, qPrintable(pixPath));
            }
        }
    }
    m_cacheKeys &lt;&lt; key;
    QFileInfo info(m_themePath);
    QDateTime mtime = info.lastModified();
    FsUtils::touch(m_themePath, mtime.addSecs(1));
}
</pre>
<p>Один хороший человек подсказал, что правильней будет хранить изображения в </p>
<pre class="brush: csharp; title: ; notranslate">/usr/share/pixmaps/skype/</pre>
<p>Результат:<br />
<img src="http://webguruz.ru/wp-content/uploads/shutter06092014001719.png" alt="" title="shutter06092014001719" width="365" height="32" class="aligncenter size-full wp-image-1267" /></p>
<p>Прикрепляю свои файлы иконок:<br />
<a href='http://webguruz.ru/wp-content/uploads/skype_icons.zip'>svg</a><br />
<a href='http://webguruz.ru/wp-content/uploads/skype-tray-png.tar.gz'>png</a></p>
<p><a href="http://habrahabr.ru/sandbox/83567/" rel="nofollow">Навеяно</a><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/ubuntu/%d0%b7%d0%b0%d0%bc%d0%b5%d0%bd%d0%b0-%d0%b8%d0%ba%d0%be%d0%bd%d0%ba%d0%b8-skype-%d0%b2-ubuntu/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Сглаживание шрифтов и глобальное меню в PhpStorm</title>
		<link>http://webguruz.ru/ubuntu/%d1%81%d0%b3%d0%bb%d0%b0%d0%b6%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%88%d1%80%d0%b8%d1%84%d1%82%d0%be%d0%b2-%d0%b8-%d0%b3%d0%bb%d0%be%d0%b1%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b5-%d0%bc%d0%b5%d0%bd/</link>
		<comments>http://webguruz.ru/ubuntu/%d1%81%d0%b3%d0%bb%d0%b0%d0%b6%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%88%d1%80%d0%b8%d1%84%d1%82%d0%be%d0%b2-%d0%b8-%d0%b3%d0%bb%d0%be%d0%b1%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b5-%d0%bc%d0%b5%d0%bd/#comments</comments>
		<pubDate>Fri, 25 Oct 2013 20:13:46 +0000</pubDate>
		<dc:creator>dimaz</dc:creator>
				<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1160</guid>
		<description><![CDATA[При разработке в ubuntu использую IDE PhpStrom, но в ней немного напрягает то, что шрифты в редакторе выглядят просто ужасно. На просторах интернета нашел решение, установить пропатченный OpenJDK, который поддерживает сглаживание шрифтов в swing приложениях. После этого редактируем конфиг IDE. Добавляем в него следующие строки Если этот вариант не помог, то пробуем следующий способ: Создадим [...]]]></description>
			<content:encoded><![CDATA[<p>При разработке в ubuntu использую IDE PhpStrom, но в ней немного напрягает то, что шрифты в редакторе выглядят просто ужасно. На просторах интернета нашел решение, установить пропатченный OpenJDK, который поддерживает сглаживание шрифтов в swing приложениях.<br />
<span id="more-1160"></span></p>
<pre class="brush: bash; title: ; notranslate">sudo add-apt-repository ppa:no1wantdthisname/openjdk-fontfix
sudo apt-get update
sudo apt-get install openjdk-7-jdk</pre>
<p>После этого редактируем конфиг IDE.</p>
<pre class="brush: bash; title: ; notranslate">gedit /opt/phpstorm/phpstorm.vmoptions</pre>
<p>Добавляем в него следующие строки</p>
<pre class="brush: bash; title: ; notranslate">-Dawt.useSystemAAFontSettings=on
-Dsun.java2d.xrender=true</pre>
<p>Если этот вариант не помог, то пробуем следующий способ:<br />
Создадим файл запуска IDE, с новыми параметрами. Для этого перейдем в папку с установленным PhpStrom, у меня он установлен в /opt/phpstorm. В директории bin создадим файл start.sh со следующим содержимым:</p>
<pre class="brush: bash; title: ; notranslate">#!/bin/sh
# путь до IDE
IDEA_HOME=/opt/phpstorm
# путь может отличаться, проверьте у себя точный путь до java
export JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
# &amp;quot;-Dawt.useSystemAAFontSettings=on&amp;quot; по мне с параметром &amp;quot;on&amp;quot; лучше всего отрисовываются шрифты.
export _JAVA_OPTIONS=&amp;quot;-Dawt.useSystemAAFontSettings=on \
                      -Dsun.java2d.xrender=true&amp;quot;
export GNOME_DESKTOP_SESSION_ID=this-is-deprecated
exec $IDEA_HOME/bin/phpstorm.sh &amp;quot;$@&amp;quot;</pre>
<p>Теперь редактируем .desktop файл запуска приложения.<br />
У меня он находится в ~/.local/share/applications/. Открываем файл в редакторе</p>
<pre class="brush: bash; title: ; notranslate">gedit ~/.local/share/applications/jetbrains-phpstorm.desktop</pre>
<p>Заменяем путь до исполняемого файла,</p>
<pre class="brush: bash; title: ; notranslate">Exec=&quot;/opt/phpstorm/bin/start.sh&quot; %f</pre>
<p>После этого все должно заработать.</p>
<p>Для большей интеграцией с ubuntu нехватает поддержка global menu. Попробуем исправить это.<br />
Первым делом доставим программы, которые нам понадобятся для пересборки java (после они нам не понадобятся, их можно будет удалить).</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install openjdk-7-jdk libunity-dev libxt-dev gcc make ant</pre>
<p>Скачиваем исходники jayatana</p>
<pre class="brush: bash; title: ; notranslate">svn checkout http://java-swing-ayatana.googlecode.com/svn/tags/1.2.4/jayatana</pre>
<p>Переходим в папку с исходниками:</p>
<pre class="brush: bash; title: ; notranslate">cd ./jayatana</pre>
<p>И пересобираем:</p>
<p>Для OpenJDK 7:</p>
<pre class="brush: bash; title: ; notranslate">sudo ant deinstall
sudo ant install
sudo ant config</pre>
<p>Для Oracle JDK 7:</p>
<pre class="brush: bash; title: ; notranslate">sudo ant deinstall
sudo ant install -Djava.home.7=/usr/lib/jvm/oraclejdk7
sudo ant config -Djava.home.7=/usr/lib/jvm/oraclejdk7</pre>
<p>Все исходники jayatana нам больше не нужны. Можно удалить</p>
<pre class="brush: bash; title: ; notranslate">rm -rf ./jayatana</pre>
<p>Запускаем PhpStrorm и любуемся <img src='http://webguruz.ru/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<a href="http://webguruz.ru/wp-content/uploads/phpstorm.png" rel="lightbox[1160]" title="phpstorm"><img src="http://webguruz.ru/wp-content/uploads/phpstorm-300x168.png" alt="" title="phpstorm" width="300" height="168" class="aligncenter size-medium wp-image-1153" /></a></p>
<p><strong>UPD:</strong> Для 13.04 и 14.04 есть репозиторий c глобальным меню:</p>
<pre class="brush: bash; title: ; notranslate">sudo add-apt-repository ppa:danjaredg/jayatana
sudo apt-get update
sudo apt-get install jayatana</pre>
<p>Вернуть обратно:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get --purge remove jayatana libjayatana libjayatanaag libjayatana-java libjayatanaag-java</pre>
<p>Вернуть обратно стандартное сглаживание:</p>
<pre class="brush: bash; title: ; notranslate">sudo apt-get install ppa-purge
sudo ppa-purge ppa:no1wantdthisname/openjdk-fontfix</pre>
<p><strong>UPD:</strong> Для пользователей Oracle JDK есть способ сгладить шрифты. Для этого нужно удалить из файла шрифта инструкции по отрисовке. Сделать это можно с помощью FontForge. </p>
<ul>
<li>Открываем нужный шрифт в FontForge.</li>
<li>Выбираем все символы Ctrl+A и удаляем инфо (Hints -> Clear Hints)</li>
<li>Снова выбираем все и удаляем инструкции (Hints -> Clear Instruction)</li>
<li>Сохраняем шрифт под другим именем ( File -> Generate Fonts)</li>
</ul>
<p>Устанавливаем шрифт в системе и выбираем в phpstorm. <!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/ubuntu/%d1%81%d0%b3%d0%bb%d0%b0%d0%b6%d0%b8%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d1%88%d1%80%d0%b8%d1%84%d1%82%d0%be%d0%b2-%d0%b8-%d0%b3%d0%bb%d0%be%d0%b1%d0%b0%d0%bb%d1%8c%d0%bd%d0%be%d0%b5-%d0%bc%d0%b5%d0%bd/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Создание Excel документа XLSX на PHP с помощью PHPExcel</title>
		<link>http://webguruz.ru/web-developer/excel-xlsx-php/</link>
		<comments>http://webguruz.ru/web-developer/excel-xlsx-php/#comments</comments>
		<pubDate>Wed, 03 Jul 2013 12:17:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web-разработка]]></category>
		<category><![CDATA[background phpexcel]]></category>
		<category><![CDATA[phpexcel]]></category>
		<category><![CDATA[генерация excel php]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1129</guid>
		<description><![CDATA[Часто на сайтах требуется выгрузка каких либо данных в формате excel (xslx). Естественно все хотят чтоб документ был уже сразу на выходе красиво оформлен. Недавно и мне потребовалось сделать такую выгрузку на php. Принято было решение использовать библиотеку PHPExcel &#8211; ее можно скачать тут http://phpexcel.codeplex.com В скачанном вами архиве очень много документации и примеров, библиотека [...]]]></description>
			<content:encoded><![CDATA[<p>Часто на сайтах требуется выгрузка каких либо данных в формате excel (xslx). Естественно все хотят чтоб документ был уже сразу на выходе красиво оформлен. Недавно и мне потребовалось сделать такую выгрузку на php. Принято было решение использовать библиотеку <strong>PHPExcel</strong> &#8211; ее можно скачать тут <noindex><a href="http://phpexcel.codeplex.com/" rel="nofollow">http://phpexcel.codeplex.com</a></noindex></p>
<p>В скачанном вами архиве очень много документации и примеров, библиотека позволяет все от простого форматирования текста и формата ячеек до создания красивых графиков.</p>
<p>В моем случае, нужно было просто закрасить ячейку в нужный цвет в зависимости от значения в данной ячейке.<br />
Подключаем библиотеку, указываем данные нашего документа:</p>
<pre class="brush: php; title: ; notranslate">
require_once 'phpexcel/Classes/PHPExcel.php';

// Create new PHPExcel object

$objPHPExcel = new PHPExcel();

// Set document properties

$objPHPExcel-&gt;getProperties()-&gt;setCreator('test')
    -&gt;setLastModifiedBy('test')
    -&gt;setTitle('test')
    -&gt;setSubject('test')
    -&gt;setDescription('test')
    -&gt;setKeywords('test')
    -&gt;setCategory('test');
</pre>
<p><span id="more-1129"></span><br />
Далее инициализируем возможные стили для ячеек, я указал border(границы) и background (закраску цветом):</p>
<pre class="brush: php; title: ; notranslate">
$red = new PHPExcel_Style();
$yellow = new PHPExcel_Style();
$green = new PHPExcel_Style();

$red-&gt;applyFromArray(
    array('fill'    =&gt; array(
        'type'      =&gt; PHPExcel_Style_Fill::FILL_SOLID,
        'color'     =&gt; array('rgb' =&gt; 'FF3333')
        ),
        'borders' =&gt; array(
            'bottom'    =&gt; array('style' =&gt; PHPExcel_Style_Border::BORDER_THIN),
            'right'     =&gt; array('style' =&gt; PHPExcel_Style_Border::BORDER_THIN)
        )

    ));

$yellow-&gt;applyFromArray(
    array('fill'    =&gt; array(
        'type'      =&gt; PHPExcel_Style_Fill::FILL_SOLID,
        'color'     =&gt; array('rgb' =&gt; 'FFFF66')
        ),
        'borders' =&gt; array(
            'bottom'    =&gt; array('style' =&gt; PHPExcel_Style_Border::BORDER_THIN),
            'right'     =&gt; array('style' =&gt; PHPExcel_Style_Border::BORDER_THIN)
        )
    ));

$green-&gt;applyFromArray(
    array('fill'    =&gt; array(
        'type'      =&gt; PHPExcel_Style_Fill::FILL_SOLID,
        'color'     =&gt; array('rgb' =&gt; '66CC66')
        ),
        'borders' =&gt; array(
            'bottom'    =&gt; array('style' =&gt; PHPExcel_Style_Border::BORDER_THIN),
            'right'     =&gt; array('style' =&gt; PHPExcel_Style_Border::BORDER_THIN)
        )
    ));
</pre>
<p>Далее нам нужно внести данные в таблицу excel, делается это очень просто. Для того чтоб было быстрее я использовал метод <em>fromArray</em>:</p>
<pre class="brush: php; title: ; notranslate">
$objPHPExcel-&gt;getActiveSheet()-&gt;fromArray($data_arr, NULL, 'A1'); // A1 - ячейка с которой начинаем вставку
</pre>
<p>А лишь потом делал закраску ячеек цветом ($data_arr &#8211; массив с данными)</p>
<pre class="brush: php; title: ; notranslate">
$temp=array('B'=&gt;'first','C'=&gt;'second','D'=&gt;'third','E'=&gt;'fourth','F'=&gt;'fifth','G'=&gt;'sixth');

foreach($data_arr as $r =&gt; $dataRow) {
    $row = $baseRow + $r;

    foreach($temp as $k=&gt;$t) {
        $color=getStyle($dataRow[$t]);
        // выставляем нужный цвет
        $objPHPExcel-&gt;getActiveSheet()-&gt;setSharedStyle($$color, $k.''.$row);
    }

}

function getStyle($value) {
    if ($value &lt;= 45 &amp;&amp; $value &gt;= 0)
        return 'green';
    elseif ($value &gt; 45 &amp;&amp; $value &lt; 50)
        return 'yellow';
    else
        return 'red';
}
</pre>
<p>Для 10 тысяч строк этот случай обрабатывался гораздо быстрее чем тот, где мы построчно заносим данные в xlsx документ:</p>
<pre class="brush: php; title: ; notranslate">
foreach($data_arr as $r =&gt; $dataRow) {
    $row = $baseRow + $r;
    $objPHPExcel-&gt;getActiveSheet()-&gt;insertNewRowBefore($row,1);

    foreach($temp as $k=&gt;$t) {
        $color=getStyle($dataRow[$t]);
        $objPHPExcel-&gt;getActiveSheet()-&gt;setCellValue($k.''.$row, $dataRow[$t])-&gt;setSharedStyle($$color, $k.''.$row);
    }
}
</pre>
<p>Так же можно вручную указать ширину колонке, например самая первая колонка у меня должна была быть немного шире чем обычно:</p>
<pre class="brush: php; title: ; notranslate">$objPHPExcel-&gt;getActiveSheet()-&gt;getColumnDimension('A')-&gt;setWidth(20);</pre>
<p>Форматирование закончено, можем сохранить файл созданный с помощью php генератора excel файла в формате xlsx:</p>
<pre class="brush: php; title: ; notranslate">
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter-&gt;save('filename.xlsx');
</pre>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/web-developer/excel-xlsx-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Denwer (настройка apache) &#8211; доступ к сайту из локальной сети</title>
		<link>http://webguruz.ru/web-developer/denwer-local-site-share/</link>
		<comments>http://webguruz.ru/web-developer/denwer-local-site-share/#comments</comments>
		<pubDate>Sun, 30 Jun 2013 16:33:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web-разработка]]></category>
		<category><![CDATA[apache denwer]]></category>
		<category><![CDATA[denwer локальная сеть]]></category>
		<category><![CDATA[доступ к denwer по локальной сети]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1121</guid>
		<description><![CDATA[Для того чтоб сайт поднятый на вашем локальном компьютере стал доступен с другого компьютера подключенного к вашей сети необходимо сделать следующее: 1. Идем в C:/WebServers/usr/local/apache/conf/httpd.conf и указываем серверу apache слушать 80 порт (данная строка по умолчанию закомментирована в целях безопасности, т.к. у denwer есть права админстратора) мы ее раскомментируем. 2. В этом же файле изменим [...]]]></description>
			<content:encoded><![CDATA[<p>Для того чтоб сайт поднятый на вашем локальном компьютере стал доступен с другого компьютера подключенного к вашей сети необходимо сделать следующее:</p>
<p>1. Идем в <em>C:/WebServers/usr/local/apache/conf/httpd.conf</em> и указываем серверу apache слушать 80 порт (данная строка по умолчанию закомментирована в целях безопасности, т.к. у denwer есть права админстратора) мы ее раскомментируем.</p>
<pre class="brush: php; title: ; notranslate">
#Listen 80

заменим на:

Listen 80
</pre>
<p><span id="more-1121"></span><br />
2. В этом же файле изменим немного шаблон генерации настройки вирутальных хостов apache:</p>
<pre class="brush: php; title: ; notranslate">
#Listen $&amp;{ip:-127.0.0.1}:$&amp;{port:-80}
#NameVirtualHost $&amp;{ip:-127.0.0.1}:$&amp;{port:-80}
#&lt;VirtualHost $&amp;{ip:-127.0.0.1}:$&amp;{port:-80}&gt;

заменим на:

##Listen $&amp;{ip:-127.0.0.1}:$&amp;{port:-80}
#NameVirtualHost $&amp;{ip:-*}:$&amp;{port:-80}
#&lt;VirtualHost $&amp;{ip:-*}:$&amp;{port:-80}&gt;
</pre>
<p>3. Отключаем брендмауер windows, для того чтоб 80 порт стал доступен извне, возможно придется проверить антивирус чтоб они не блокировали нужный нам порт.<br />
Проверку доступности порта можно проверить со второго компьютера командой:</p>
<pre class="brush: php; title: ; notranslate">telnet ип-компьютера-с-сайтом 80</pre>
<p>4. На втором компьютере в файл hosts (в windows находится в c:/windows/sistem32/drivers/etc/hosts) прописываем сайт который хотим просмотреть:</p>
<pre class="brush: php; title: ; notranslate">ип-компьютера-с-сайтом example.ru</pre>
<p>Перезапускаем apache, denwer, и проверяем доступность сайта со второго компьютера вбив в адресную строку либо ип нужного нам компьютера либо введенный в hosts <em>example.ru</em><br />
<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/web-developer/denwer-local-site-share/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Релевантный поиск по сайту (Yandex API + PHP +MySql)</title>
		<link>http://webguruz.ru/web-developer/relevant-site-search/</link>
		<comments>http://webguruz.ru/web-developer/relevant-site-search/#comments</comments>
		<pubDate>Tue, 25 Jun 2013 15:59:05 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web-разработка]]></category>
		<category><![CDATA[поиск по сайту php]]></category>
		<category><![CDATA[релевантный поиск mysql]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1107</guid>
		<description><![CDATA[Поиск по сайту &#8211; необходиый инструмент при создании любого сайта (от визитки до социальной сети). Этому посвящено уже много статей, найти которые не составит для вас труда, но все они рассказывают об очень посредственном поиске. Я хочу рассказать о том как легко и без особых усилий вы можете сделать умный поиск на своем сайте. Под [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Поиск по сайту</strong> &#8211; необходиый инструмент при создании любого сайта (от визитки до социальной сети). Этому посвящено уже много статей, найти которые не составит для вас труда, но все они рассказывают об очень посредственном поиске. Я хочу рассказать о том как легко и без особых усилий вы можете сделать умный поиск на своем сайте. Под умным поиском я понимаю следующее:</p>
<p>1) проверка правописания в поисковой фразе<br />
2) выделение корней значимых слов (stemming)<br />
3) релевантный поиск по значимым словам<br />
<span id="more-1107"></span></p>
<p>1) Проверку правописания выполним с помощью яндекс сервиса Speller (<a href="http://api.yandex.ru/speller/doc/dg/concepts/api-overview.xml">подробная документация</a>)<br />
Как мы видим в описании api yandex, нам необходимо отправить get запросом текст который нужно проверить в ответ мы получим данные по проверке (в документации все подробно описано поэтому не буду вдаваться в подробности). <em>$str</em> &#8211; поисковая фраза которую нужно проверить на правописание. Ответ от сервиса я получаю в формате json, если есть варианты исправления правописания то вывожу их на экран: </p>
<pre class="brush: php; title: ; notranslate">
$checker=json_decode(file_get_contents(&quot;http://speller.yandex.net/services/spellservice.json/checkText?text=&quot;.urlencode($str)));
$checked_str=$str;
foreach($checker as $word) {
	$checked_str=str_replace($word-&gt;word,$word-&gt;s[0],$checked_str);
}
if(mb_strtolower($checked_str,'utf8')!=mb_strtolower($str,'utf8') &amp;&amp; !empty($checked_str)) {
	echo &quot;Возможно вы имели ввиду: &lt;a href=\&quot;/search/$checked_str\&quot;&gt;$checked_str&lt;/a&gt;&quot;;
}
</pre>
<p>2) Выделим корни значимых слов (stemming)<br />
Для этого нам понадобится готовый класс стемминга на php, он использует стемммер Портера:<br />
<a href='http://webguruz.ru/wp-content/uploads/stemming.zip'>скачать stemming.zip</a><br />
Код данного класса не мой, скачал с какого то форума немного подправил для работы в кодировке utf8, к сожалению не смог найти ссылку на источник.<br />
Используем выше определенный класс для выделения корней слов, на выходе получаем фразу без окончаний и предлогов, а так же без вспомогательных слов таких как <em>в, на</em> и тд.</p>
<pre class="brush: php; title: ; notranslate">
$stemming= new Stemming();
$stem_str=$stemming-&gt;stem_string($str);
</pre>
<p>3) Релевантный поиск организуем с помощью mysql и php. Генерируем запрос к базе в котором будем также рассчитывать коеффициент релевантности найденного результата. Коэффициент релевантности для каждой колонки указывается в массиве. Причем полное соответствие поисковому запросу будет иметь больший коэффициент релевантности чем найденное одно или несолько слов из запроса. Для колонки с названием продукта я поставил больший коэффициент чем за колонку с описанием, что тоже вполне логично чтоб поиск по сайту был более адекватным.</p>
<pre class="brush: php; title: ; notranslate">
$search_req = &quot; AND ( &quot;;
$search_array = explode(&quot; &quot;, $stem_str);

$search_str=preg_replace(&quot;/[^а-яА-Яa-zA-z0-9\-]/ui&quot;,&quot;%&quot;,$stem_str); //заменяем все знаки кроме цифр и букв на % (любое кол-во любых символов)

// массив колонок по которым ищем и их коэффицент релевантности
$search_columns=array(
	'prod.title'=&gt;'20',
	'prod.small_descr'=&gt;'10',
	'prod.articul'=&gt;'15',
	'prod.maker'=&gt;'15',
	'sscat.title'=&gt;'10',
	);

$select =&quot;, ( 0&quot;;
$search_req_arr=array();

foreach($search_columns as $col=&gt;$coeff) {
	// полнотекстовый
	$select.= &quot; + IF ($col LIKE '&quot;.$search_str.&quot;', $coeff*3, 0)&quot;;
	$search_req_arr[]= &quot; $col LIKE '%&quot;.$search_str.&quot;%'&quot;;

	// для отдельного слова
	$word_coeff=round(($coeff/count($search_array)),2);

	foreach($search_array as $word) {
		$select .= &quot;+ IF ($col LIKE '%&quot;.$word.&quot;%', &quot;.$word_coeff.&quot;, 0)&quot;;
		$search_req_arr[] = &quot;$col LIKE '%&quot;.$word.&quot;%'&quot;;
	}
}
$select.=&quot;) AS `relevant`&quot;;
$search_req .=implode(&quot; OR &quot;,$search_req_arr);
$search_req .= &quot;)&quot;;

$query=&quot;SELECT prod.id, prod.title, prod.price, prod.description prod.isnew, prod.ishit, prod.small_descr $select
FROM ss_products prod
WHERE prod.status = '1' $search_req
ORDER BY relevant DESC LIMIT 0, 20&quot;;
</pre>
<p>В итоге получился вот такой запрос в базу данных:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT prod.id, prod.title, prod.price, prod.description prod.isnew, prod.ishit, prod.small_descr ,
( 0 + IF (prod.title LIKE 'насос%вод', 20*3, 0)+ IF (prod.title LIKE '%насос%', 10, 0)+
IF (prod.title LIKE '%вод%', 10, 0) + IF (prod.small_descr LIKE 'насос%вод', 10*3, 0)+
IF (prod.small_descr LIKE '%насос%', 5, 0)+ IF (prod.small_descr LIKE '%вод%', 5, 0) +
IF (prod.articul LIKE 'насос%вод', 15*3, 0)+ IF (prod.articul LIKE '%насос%', 7.5, 0)+
IF (prod.articul LIKE '%вод%', 7.5, 0) + IF (prod.maker LIKE 'насос%вод', 15*3, 0)+
IF (prod.maker LIKE '%насос%', 7.5, 0)+ IF (prod.maker LIKE '%вод%', 7.5, 0)) AS `relevant`
FROM ss_products prod
WHERE prod.status = '1' AND (
prod.title LIKE '%насос%вод%' OR prod.title LIKE '%насос%' OR prod.title LIKE '%вод%' OR
prod.small_descr LIKE '%насос%вод%' OR prod.small_descr LIKE '%насос%' OR prod.small_descr LIKE '%вод%'
OR prod.articul LIKE '%насос%вод%' OR prod.articul LIKE '%насос%' OR prod.articul LIKE '%вод%'
OR prod.maker LIKE '%насос%вод%' OR prod.maker LIKE '%насос%' OR prod.maker LIKE '%вод%'
)
ORDER BY relevant DESC LIMIT 0, 20
</pre>
<p>Не бойтесь не смотря на много IF, запрос отрабатывает очень быстро и хорошо справляется с задачей организации релевантного поиска на сайте. </p>
<p>В моем случае в поисковом запросе я набрал фразу <em>нососы для воды</em>, специально сделав ошибку в одном слове. После прохождения через yandex speller скрипт мне предложил правильный вариант <em>насосы для воды</em>. Затем поисковая фраза прошла через stemming и на выходе отдала вразу <em>насос вод</em>. По этой фразе мы и выполняем релевантный поиск по сайту. В моем случае с увернностью можно сказать что в результате найдено то что искал пользователь, когда коэффициет релевантности больше 70.<br />
Надеюсь теперь больше сайтов будут иметь адекватный красивый поиск.<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/web-developer/relevant-site-search/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Cортировка в CGridView</title>
		<link>http://webguruz.ru/news/sort_in-cgridview/</link>
		<comments>http://webguruz.ru/news/sort_in-cgridview/#comments</comments>
		<pubDate>Mon, 17 Jun 2013 20:41:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[Новости IT]]></category>
		<category><![CDATA[cgridview]]></category>
		<category><![CDATA[yii]]></category>
		<category><![CDATA[yii grid sort]]></category>
		<category><![CDATA[yii sort cgridview]]></category>
		<category><![CDATA[сортировка grid]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1098</guid>
		<description><![CDATA[Как сделать сортировку в Grid на фреймворке Yii? Как запретить сортировку по тем или иным колонкам? Как настроить сортировку таблицы по какому либо полю по умолчанию (или по дефолту)? С этими вопросами сталкиваются как новички так и опытные программисты, вобщем все кому приходилось работать с фреймворком Yii. На все выше перечисленные вопросы вы найдете ответ [...]]]></description>
			<content:encoded><![CDATA[<p>Как сделать сортировку в Grid на фреймворке Yii? Как запретить сортировку по тем или иным колонкам? Как настроить сортировку таблицы по какому либо полю по умолчанию (или по дефолту)? С этими вопросами сталкиваются как новички так и опытные программисты, вобщем все кому приходилось работать с фреймворком Yii. На все выше перечисленные вопросы вы найдете ответ в этом посте.</p>
<p>На самом деле все делается очень просто, как вы знаете в <em>CGridView</em> передается <em>CActiveDataProvider</em> который определяется прям во вьюхе, либо в модели. В любом случае нам лишь нужно передать необходимый параметр <em>sort</em>.</p>
<p>В своем примере я покажу это на примере таблицы Banners. В методе search зададим список колонок по которым разрешена сортировка, для этого тоже имеется несколько способов:<br />
1. Указать массив названий колонок по которым разрешена сортировка:</p>
<pre class="brush: php; title: ; notranslate">
$dataProvider = new CActiveDataProvider('Banners', array(
   'sort'=&gt;array('attributes'=&gt;array('id','name')), // названия колонок по которым разрешена сортировка
));
</pre>
<p><span id="more-1098"></span><br />
2. С помощью класса <em>CSort</em>, с помощью которого мы так же можем указать сортировку в связанных таблицах (в моем случае <em>page.title</em>). Так же обратите внимание что с помощью ключа <em>defaultOrder</em> можно задать параметры сортировки по умолчанию.</p>
<pre class="brush: php; title: ; notranslate">
$sort = new CSort();
$sort-&gt;attributes = array(
    'defaultOrder'=&gt;'t.date DESC',
    'id'=&gt;array(
        'asc'=&gt;'t.id',
        'desc'=&gt;'t.id DESC',
    ),
    'name'=&gt;array(
        'asc'=&gt;'t.name',
        'desc'=&gt;'t.name DESC',
    ),
    'pageTitle'=&gt;array(
        'asc'=&gt;'page.title',
        'desc'=&gt;'page.title desc',
    ),
);

return new CActiveDataProvider('Banners', array(
    'criteria'=&gt;$criteria,
    'sort'=&gt;$sort
));
</pre>
<p>В CGridView нам остается лишь передать объект класса CActiveDataProvider, и все отлично заработает.</p>
<pre class="brush: php; title: ; notranslate">
$this-&gt;widget('zii.widgets.grid.CGridView', array(
    'id' =&gt; 'articles-grid',
    'dataProvider' =&gt; $model-&gt;search(),
    'columns' =&gt; $columns,
));
</pre>
<p>Вот таким не хитрым способом настраивается сортировка в CGridView в замечательном фреймворке Yii. <!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/news/sort_in-cgridview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Yii extension CKEditor с бесплатным файловым менеджером</title>
		<link>http://webguruz.ru/web-developer/yii/yii-extension-ckeditor-kcfinder/</link>
		<comments>http://webguruz.ru/web-developer/yii/yii-extension-ckeditor-kcfinder/#comments</comments>
		<pubDate>Sat, 15 Jun 2013 05:20:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Yii]]></category>
		<category><![CDATA[ckeditor]]></category>
		<category><![CDATA[yii ckeditor]]></category>
		<category><![CDATA[yii extension ckeditor]]></category>
		<category><![CDATA[yii kcfinder]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1057</guid>
		<description><![CDATA[Для подключения CKEditor к YII, я использовал расширения из yiiext. Скачиваем его и распаковываем в каталлог с расширениями. У меня получилось: application.extensions.ckeditor Теперь создаем в этом каталоге, папку assets и распаковываем туда файлы самого CKEditor, которые скачиваем с официально сайта (я скачал ckeditor 4). Виджет отказался запускаться ссылаясь на некоторые ошибки. Чтобы он заработал открываем [...]]]></description>
			<content:encoded><![CDATA[<p>Для подключения CKEditor к YII, я использовал расширения из yiiext. Скачиваем его и распаковываем в каталлог с расширениями. У меня получилось: <em>application.extensions.ckeditor</em></p>
<p>Теперь создаем в этом каталоге, папку assets и распаковываем туда файлы самого CKEditor, которые скачиваем с официально сайта (я скачал ckeditor 4). Виджет отказался запускаться ссылаясь на некоторые ошибки. Чтобы он заработал открываем файл ECKEditor.php идем на строку 69 и меняем:</p>
<pre class="brush: php; title: ; notranslate">private $skin='moono';
на
public $skin='moono'; // тут также можем указать свою тему</pre>
<p>Дальше функция setLanguage($value), меняем:</p>
<pre class="brush: php; title: ; notranslate">
if(isset($this-&gt;allowedLanguages[$language]))
    $this-&gt;language=$language;
на
if(isset($this-&gt;allowedLanguages[$lang]))
    $this-&gt;language=$lang;
</pre>
<p>Теперь виджет можно подключить следующим образом, как стандартный виджет yii.<br />
<span id="more-1057"></span></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php $this-&gt;widget('application.extensions.ckeditor.ECKEditor', array(
			'model'=&gt;$model,
			'attribute'=&gt;'html',
			'language'=&gt;'ru',
			'editorTemplate'=&gt;'full',
			'height'=&gt;'500px'
)); ?&gt;
</pre>
<p><em>editorTemplate</em> может быть также <em>basic</em>. В CKEditor 4 в конфигах не получается указать сразу несколько шаблонов как в предыдущих версиях редактора, поэтому в коде extesions дописал при выборе basic версии, такой вот код в replace:</p>
<pre class="brush: php; title: ; notranslate">
if($this-&gt;editorTemplate=='basic') {
			$js =&lt;&lt;&lt;EOP
CKEDITOR.replace('{$name}', { toolbarGroups : [

		{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
		{ name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },
		{ name: 'styles' },
		{ name: 'colors' }],
		height: '$this-&gt;height'});
EOP;
		}
		else {
			$js =&lt;&lt;&lt;EOP
CKEDITOR.replace('{$name}',{$options});
EOP;
		}
</pre>
<p>Также добавил настройки форматирования кода в редакторе и файл менеджер KCFinder для загрузки файлов через CKEditor, которые описывал тут: <a href="http://webguruz.ru/web-developer/ckfinder_in_ckeditor_config/">Настройка CKEditor 4, подключение файлменеджера KCFinder</a></p>
<p>Чтобы вам все это заново не делать, собрал все в один extension для Yii, архив нужно распаковать в <em>/protected/extensions/</em>, в корне сайта должна быть папка <em>upload</em> с правами на запись (туда будут складываться загруженные через редактор файлы)</p>
<p><a href='http://webguruz.ru/wp-content/uploads/ckeditor.zip'>Скачть Yii extension CKEditor c файлменеджером</a></p>
<p>Надеюсь что это сэкономит кому то не мало времени.<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/web-developer/yii/yii-extension-ckeditor-kcfinder/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Настройка CKEditor 4, подключение файлменеджера KCFinder</title>
		<link>http://webguruz.ru/web-developer/ckfinder_in_ckeditor_config/</link>
		<comments>http://webguruz.ru/web-developer/ckfinder_in_ckeditor_config/#comments</comments>
		<pubDate>Fri, 14 Jun 2013 17:02:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Web-разработка]]></category>
		<category><![CDATA[ckeditor]]></category>
		<category><![CDATA[ckeditor настройка]]></category>
		<category><![CDATA[ckfinder]]></category>
		<category><![CDATA[ckfinder in ckeditor]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1078</guid>
		<description><![CDATA[Обычно WYSIWYG редактор требуется когда необходимо написать админку, в которой обычному пользователю не знающему html, будет легко и удобно добавлять собственные тексты. Так было и в моем случае. Скачиваем CKEditor с официального сайта: скачать ckeditor Скачиваем бесплатный файл менеджер KCFinder: скачать kcfinder Стандартным способом интегрируем CKEditor на сайт. Добавляем на страницу скрипт ckeditor.js (в моем [...]]]></description>
			<content:encoded><![CDATA[<p>Обычно WYSIWYG редактор требуется когда необходимо написать админку, в которой обычному пользователю не знающему html, будет легко и удобно добавлять собственные тексты. Так было и в моем случае. </p>
<p>Скачиваем CKEditor с официального сайта: <noindex><a href="http://ckeditor.com/download" rel="nofollow">скачать ckeditor</a></noindex><br />
Скачиваем бесплатный файл менеджер KCFinder: <noindex><a href="http://kcfinder.sunhater.com/" rel="nofollow">скачать kcfinder</a></noindex></p>
<p>Стандартным способом интегрируем CKEditor на сайт. Добавляем на страницу скрипт ckeditor.js (в моем случае скрипт лежит в корне сайта в каталоге ckeditor). KCFinder я распаковал в папку ckeditor, просто для удобства.</p>
<pre class="brush: xml; title: ; notranslate">&lt;script src=&quot;/ckeditor/ckeditor.js&quot;&gt;&lt;/script&gt;</pre>
<p>Пусть на странице имеется поле textarea которое нужно заменить WYSIWYG редактором:</p>
<pre class="brush: xml; title: ; notranslate">&lt;textarea name=&quot;ckeditor&quot;&gt;&lt;/textarea&gt;
&lt;script&gt;
   CKEDITOR.replace( 'ckeditor' );
&lt;/script&gt;
</pre>
<p><span id="more-1078"></span><br />
Далее нам необходимо указать настройки в ckeditor для того чтоб при нажатии на кнопку &laquo;загрузить файл&raquo; или просмотреть файлы на сервере открывался KCFinder, для этого добавляем в CKEDITOR.replace следующие настройки:</p>
<pre class="brush: jscript; title: ; notranslate">CKEDITOR.replace('ckeditor',{'filebrowserBrowseUrl':'/ckeditor/kcfinder/browse.php?type=files',
	'filebrowserImageBrowseUrl':'/ckeditor/kcfinder/browse.php?type=images',
	'filebrowserFlashBrowseUrl':'/ckeditor/kcfinder/browse.php?type=flash',
	'filebrowserUploadUrl':'/ckeditor/kcfinder/upload.php?type=files',
	'filebrowserImageUploadUrl':'/ckeditor/kcfinder/upload.php?type=images',
	'filebrowserFlashUploadUrl':'/ckeditor/kcfinder/upload.php?type=flash'});
</pre>
<p>В каталоге /ckeditor/kcfinder/ есть скрипт с конфигурацией config.php, там необходимо указать путь к папке в которую будут загружаться добавленные файлы (не забудьте посмотреть чтоб директория была доступна для записи).</p>
<p>Кажется что все работает, но есть еще несколько моментов касающихся настроек форматирования кода в CKEditor, мне например не нравится что при нажатии на клавишу enter в редакторе, текст заключается в тег &lt;p>  так же этот тег постоянно записывается когда пытаемся сохранить пустое поле с подключенным редактором. Чтоб это исправить добавляем небольшой скрипт:</p>
<pre class="brush: jscript; title: ; notranslate">if(typeof CKEDITOR !== 'undefined') {

	CKEDITOR.on( 'instanceReady', function( ev ) {
		// Output paragraphs as &lt;p&gt;Text&lt;/p&gt;.
		ev.editor.dataProcessor.writer.setRules( '*', {
			indent: false,
			breakBeforeOpen: true,
			breakAfterOpen: false,
			breakBeforeClose: false,
			breakAfterClose: true
		});
	});
}</pre>
<p>Убрали автозаполнения тегом &lt;p>, теперь уберем заключение текста в данный тег при нажатии на enter. Для этого допишем следующие настройки в файл конфигурации <em>/ckeditor/config.js</em>:</p>
<pre class="brush: jscript; title: ; notranslate">

	// при нажатии enter добавляем br
	config.enterMode = CKEDITOR.ENTER_BR;
	config.shiftEnterMode = CKEDITOR.ENTER_BR;
</pre>
<p>Если кажется что последние две строчки кода не помогают решению проблемы, очистите кеш браузера и повторите тестирование, все должно работать. Таким образом ваш редактор CKEditor c файловым менеджером KCFinder готов к работе, и выглядит очень даже не плохо.</p>
<p>Дополнительную информацию по настройке конфигурации можно посмотреть на официальных сайтах редакторов.<!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/web-developer/ckfinder_in_ckeditor_config/feed/</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Apache VirtualHost &#8211; настройка, автоматическое создание</title>
		<link>http://webguruz.ru/ubuntu/apache-virtualhost/</link>
		<comments>http://webguruz.ru/ubuntu/apache-virtualhost/#comments</comments>
		<pubDate>Wed, 12 Jun 2013 15:58:04 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[apache virtualhost]]></category>
		<category><![CDATA[apache виртуальный хост]]></category>
		<category><![CDATA[apache2]]></category>
		<category><![CDATA[виртуальный хост ubuntu]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=1065</guid>
		<description><![CDATA[Работая программистом, очень часто приходится настраивать VirtualHost в Apache. Конечно это не занимает больше 10 минут, но все же время это деньги. Как же хорошо что не только denwer в windows может упростить задачу создания виртуальных хостов, в Ubuntu тоже есть такая возможность &#8211; это и есть тема данной статьи. Для начала рассмотрим процесс ручной [...]]]></description>
			<content:encoded><![CDATA[<p>Работая программистом, очень часто приходится настраивать VirtualHost в Apache. Конечно это не занимает больше 10 минут, но все же время это деньги. Как же хорошо что не только denwer в windows может упростить задачу создания виртуальных хостов, в Ubuntu тоже есть такая возможность &#8211; это и есть тема данной статьи. Для начала рассмотрим процесс ручной настройки, а затем напишем sh скрипт для автоматического создания виртуальных хостов.<br />
В каталоге <i>/etc/apache2/sites-available</i> создаём файл с именем &laquo;sitename.ru&raquo;</p>
<pre class="brush: php; title: ; notranslate">sudo gedit /etc/apache2/sites-available/sitename.ru</pre>
<p><span id="more-1065"></span><br />
в нем необходимо указать настройки хоста, я указываю такие:</p>
<pre class="brush: php; title: ; notranslate">
&lt;VirtualHost *:80&gt;
	ServerAdmin webmaster@localhost
	ServerName sitename.ru
	DocumentRoot /var/www/sitename
	&lt;Directory /&gt;
		Options All
		AllowOverride All
	&lt;/Directory&gt;
	&lt;Directory /var/www/sitename&gt;
		Options All
		AllowOverride All
		Order allow,deny
		allow from all
	&lt;/Directory&gt;
	ErrorLog /var/log/apache2/error.log
	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn
	CustomLog /var/log/apache2/access.log combined
	ServerSignature On
&lt;/VirtualHost&gt;
</pre>
<p>Теперь для того чтоб разрешить использование этого доменного имени создадим символическую ссылку в каталоге <em>/etc/apache2/sites-enabled/</em></p>
<pre class="brush: php; title: ; notranslate">
cd /etc/apache2/sites-enabled/
sudo ln -s ../sites-available/sitename.ru
</pre>
<p>либо с помощью команды</p>
<pre class="brush: php; title: ; notranslate">a2ensite /etc/apache2/sites-available/sitename.ru</pre>
<p>Теперь осталось только добавить запись о нашем виртуальном хосте в файл <em>/etc/hosts</em>, открываем файл:</p>
<pre class="brush: php; title: ; notranslate">sudo gedit /etc/hosts</pre>
<p>через пробел добавляем название нашего сайта &laquo;sitename.ru&raquo;, должна получиться строка вида, если доменов больше одного они указываются через пробел:</p>
<pre class="brush: php; title: ; notranslate">127.0.0.1 sitename.ru</pre>
<p>Перезапускаем apache, чтоб новые настройки вступили в силу, делаем это командой:</p>
<pre class="brush: php; title: ; notranslate">sudo apache2ctl restart</pre>
<p>Теперь напишем sh скрипт который сделает все то же самое автоматически. Создадим файл в папке <em>/home/username/</em>, назовем его virt-host.sh и добавим в него сам скрипт автоматического создания виртуального хоста:</p>
<pre class="brush: php; title: ; notranslate">#!/bin/bash
echo &quot;Creating Virtual Host&quot;
cd /etc/apache2/sites-available
cat &lt;&lt;EOF &gt;&gt; &quot;$1&quot;
&lt;VirtualHost *:80&gt;
	ServerAdmin webmaster@localhost
	ServerName $1
  	ServerAlias www.$1
	DocumentRoot &quot;/var/www/$1&quot;

	&lt;Directory /&gt;
		Options All
		AllowOverride All
	&lt;/Directory&gt;

	&lt;Directory &quot;/var/www/$1&quot;&gt;
		Options All
		AllowOverride All
		Order allow,deny
		allow from all
	&lt;/Directory&gt;
	ErrorLog /var/log/apache2/error.log
	# Possible values include: debug, info, notice, warn, error, crit,
	# alert, emerg.
	LogLevel warn
	CustomLog /var/log/apache2/access.log combined
	ServerSignature On
&lt;/VirtualHost&gt;
EOF
mkdir &quot;/var/www/$1&quot;
cd /etc/apache2/sites-enabled
ln -s &quot;/etc/apache2/sites-available/$1.conf&quot; &quot;$1.conf&quot;
echo &quot;Editing /etc/hosts&quot;
cat &lt;&lt;EOF &gt;&gt; &quot;/etc/hosts&quot;
127.0.0.1       $1
EOF
echo &quot;Set permissions&quot;
chmod 0777 -R &quot;/var/www/$1&quot;
echo &quot;Restarting Apache2&quot;
/etc/init.d/apache2 restart
echo &quot;Finished!&quot;
echo &quot;Local address: /var/www/$1&quot;
echo &quot;Web address: http://$1&quot;
</pre>
<p>сохраним и дадим файлу права на исполнение:</p>
<pre class="brush: php; title: ; notranslate">sudo chmod a+x virt-host.sh</pre>
<p>вот и все, скрипт готов к работе, запускаем его с помощью команды:</p>
<pre class="brush: php; title: ; notranslate">sudo ./virt-host.sh sitename.ru</pre>
<p>скрипт также создаст каталог &laquo;sitename.ru&raquo; в директории <em>/var/www/</em>, в этот каталог нам и нужно будет положить файлы нашего сайта. <!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/ubuntu/apache-virtualhost/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Grep &#8211; примеры использования</title>
		<link>http://webguruz.ru/ubuntu/grep-example/</link>
		<comments>http://webguruz.ru/ubuntu/grep-example/#comments</comments>
		<pubDate>Thu, 11 Apr 2013 10:39:12 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ubuntu]]></category>
		<category><![CDATA[grep]]></category>
		<category><![CDATA[grep -e]]></category>
		<category><![CDATA[grep -egrep]]></category>
		<category><![CDATA[grep examples]]></category>

		<guid isPermaLink="false">http://webguruz.ru/?p=973</guid>
		<description><![CDATA[Часто бывает так что необходимо найти какую либо строку в огромном проекте на битрикс, ни одна IDE не справляется с таким поиском, по крайней мере не быстро. Чтобы ускорить процесс поиска нужного кода не раз ипользовал эту замечательную команду grep в терминале ubuntu. Вот краткий справочник по командам:]]></description>
			<content:encoded><![CDATA[<p>Часто бывает так что необходимо найти какую либо строку в огромном проекте на битрикс, ни одна IDE не справляется с таким поиском, по крайней мере не быстро. Чтобы ускорить процесс поиска нужного кода не раз ипользовал эту замечательную команду <strong>grep</strong> в терминале ubuntu.</p>
<p>Вот краткий справочник по командам:</p>
<pre class="brush: sql; title: ; notranslate">
grep pattern file.txt	--поиск pattern в файле file.txt, с выводом полностью совпавшей строкой
grep -o pattern file.txt	--поиск pattern в файле file.txt и вывод только совпавшего куска строки
grep -i pattern file.txt	--игнорирование регистра при поиске
grep -bn pattern file.txt	  --показать строку (-n) и столбец (-b), где был найден pattern
grep -v pattern file.txt	 --инверсия поиска (найдет все строки, которые не совпадают с шаблоном pattern)
grep -A 3 pattern file.txt   --вывод дополнительных трех строк, после совпавшей
grep -B 3 pattern file.txt   --вывод дополнительных трех строк, перед совпавшей
grep -C 3 pattern file.txt  --вывод три дополнительные строки перед и после совпавшей
grep -r pattern $HOME  --рекурсивный поиск по директории $HOME и всем вложенным
grep -c pattern file.txt  --подсчет совпадений
grep -L pattern *.txt  --вывести список txt-файлов, которые не содержат pattern
grep -l pattern *.txt  --вывести список txt-файлов, которые содержат pattern
grep -w pattern file.txt  --совпадение только с полным словом pattern
grep -f patterns.txt file.txt --поиск по нескольким pattern из файла patterns.txt, шаблоны разделяются новой строкой
grep -I pattern file.txt  --игнорирование бинарных файлов
grep -v -f file2 file1 &gt; file3  --вывод строк, которые есть в file1 и нет в file2
grep -in -e 'python' `find -type f`  --рекурсивный поиск файлов, содержащих слово python с выводом номера строки и совпадений
grep -inc -e 'test' `find -type f` | grep -v :0  --рекурсивный поиск файлов, содержащих слово python с выводом количества совпадений
grep . *.py  --вывод содержимого всех py-файлов, предваряя каждую строку именем файла
grep &quot;Http404&quot; apps/**/*.py  --рекурсивный поиск упоминаний Http404 в директории apps в py-файлах
</pre>
<p><!-- PHP 5.x --></p>
]]></content:encoded>
			<wfw:commentRss>http://webguruz.ru/ubuntu/grep-example/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
