User Tools

Site Tools


new_rotation_faq

New Rotation FAQ

What is mod_rewrite

mod_rewrite is the Apache module for readable URLs. nginx and lighttpd provide equivalent URL rewriting features.

For example, default template URLs look like http://domain/gallery/cool-gallery/index.html, even though no such physical path exists on the server. The rewrite rule converts that URL into something like http://domain/scj/tube/?slug=cool-gallery. The human-friendly URL is there for search engines and users.

The .htaccess file created during setup contains these rewrite rules.

A simple explanation of how it works:

As mentioned above, /gallery/cool-gallery/index.html does not really exist on the server. To open that gallery directly, the real URL would have to be something like /scj/cgi/out.php?url=content&slug=cool-gallery, which is not very clean. So we add a rewrite rule to .htaccess that tells Apache how to transform one URL into another. In this case the rule is:

RewriteRule ^gallery/(.*)/index.html$ /scj/cgi/out.php?url=content&slug=$1

This means: if the URL starts with gallery/, then has some value captured by (.*), and ends with /index.html, it matches this rule. Each captured part gets its own number: the first one is $1, the second would be $2, and so on.

In this example, $1 becomes cool-gallery. Apache therefore rewrites the URL to /scj/cgi/out.php?url=content&slug=cool-gallery and the gallery is shown.

URLs like /gallery/cool-gallery/index.html appear on pages because subtemplates contain markup like this:

href="/gallery/<!--GALLERY_SLUG-->/index.html

So if you want to change the URL format on the site, you need to change both the subtemplate and the rewrite rule so they match each other.

Why does Rotation - Groups show 10 galleries, while the site or Rotation - List thumbs shows 20?

One gallery can belong to more than one group (category). You can see this when editing any thumb: it has one main group and multiple extra groups. Rotation - Groups counts only by the main group, so you can clearly see how many unique galleries there actually are.

For example, two galleries both belong to extra groups A and B. One has main group A; the other has main group B. Rotation - Stats counts two unique galleries, one in each main group. On the site, both galleries appear in each group.

  1. Upload the images to an accessible location.
  2. During import, set Image List to the list of image URLs.

What is Init cats, and why has a new category not appeared on the site?

Selecting the best category thumb and counting the thumbs in each category is expensive. Cron performs this calculation every 15 minutes and caches the result for the rest of the script. Init cats in Rotation - Special runs the calculation immediately.

If you have added a new category, it will appear in a maximum of 15 minutes, if you need it faster, click this button.

What is cache

Pages are generated dynamically rather than stored as static HTML files (see mod_rewrite above). To avoid regenerating a page for every visitor, the script caches it for CACHE_TIME. Other visitors receive the cached page until that time expires.

Set CACHE_TIME in common.php. Since update 46, you can instead leave it unset there and configure the cache lifetime in the rotation settings. A value in common.php takes precedence over the rotation settings.

In order to view a page without cache, you need to add the skip_cache=true parameter to the URL. For example, http://domain.com/?skip_cache=true

Since update 46, Rotation - Special - Recreate visited pages can set a secret cookie in your browser for 10 hours. You can remove it from the same menu. While it is present, opening a site page rebuilds that page’s cache, which is useful when editing a specific page design.

skip_cache shows an uncached page only to you. The recreate cookie also saves the rebuilt page to cache, so other visitors see the new version.

For example, a page is cached at minute 00 for 10 minutes, and you change its design at minute 05. With skip_cache, you see the new design, but a visitor at minute 06 still sees the old cached page. If you open it with the recreate cookie at minute 05, the visitor at minute 06 sees the new design too.

Cache Engines (New)

The basic principle of the engine is to generate the desired page, put it in the cache for a certain time and display it until the cache is cleared. What engines are currently available:

File Basically cache is stored in files (scj/cache - file cache). Pros - it works everywhere and at once. The disadvantages are that it is a file cache, it is not as fast, the cache system is not as efficient as we would like, and you have to separately take care of the size of the cache folder.

Memcached At one time, this was certainly a big step forward in terms of cache. Pros - everyone knows it, admins install it on hosting without any problems, it’s easy to administer, etc. Disadvantages - it is almost impossible to get any understanding of the actual memory occupied; when the server is overloaded, the entire cache is deleted and you need to “warm up the cache” to put the most used data there. When the server is overloaded due to load, this is a serious problem - the server is already loaded, and then all the cache has disappeared.

All data is cached equally - it doesn’t matter if it is the most used or used once an hour - they all hang in the same memory and the service does not know how to dump them to disk, for example.

With memcache, you cannot clear cache for one site only. All sites share the same cache space, so clearing it affects every site at once. You can of course run multiple memcache instances on different ports, but that usually requires admin help and is inconvenient in practice.

How to install:

- ask the admin to install Memcached

  1. register memcache in the config
$config['memcached_host'] = '127.0.0.1';
$config['memcached_port'] = '11211';

Therefore, now there are new engines that are recommended for use

In new engines, which are basically called NoSQL solutions, there are many more possibilities than will be described below, but for current cache purposes the basic ones will be described.

The easiest solution to switch to is Couchbase CouchBase is a continuation of MemBase, apparently the closest descendant of memcachedb, which in turn comes from memcached.

Couchbase can replace memcache with few configuration changes. To use it:

and that's it, you are already using a modern version of memcache. You can use this even with version 48-49.

How is this better than memcached

  • There is no concept of “warming up cache”. In fact, this is a file cache, but made an order of magnitude more correctly, which loads the disk much less, calculates when and how best to write data in blocks to disk, etc. In this case, the data lies in several files, and not in hundreds of files like a file cache.
  • Expired data is removed from disk and memory automatically.
  • You can, just like with memcache, limit the amount of memory allocated for cache, but cache will not be limited by this amount. Even if there is more data, it will leave the most active ones in memory and store the rest on disk. And loading the required element from disk is faster than generating it again.
  • You can quickly and easily scale the system from the web admin panel.
  • You can also create several separate caches. In Couchbase this is like running several memcache instances, but everything is managed from the web admin panel, which is much faster and more convenient. For example, you can create 10 caches, each on its own port, and assign a separate port to each site. In that setup, the long-requested “Delete all cache” button effectively becomes possible, because you can clear the full cache for one site only.
  • When moving, cache is easy to copy because it is not a lot of small files that are copied, as with a file cache, but one database.

Redis is a separate NoSQL database project written from scratch. Its meaning for our purposes is almost the same (in reality, couchBase is more of a document oriented storage, and Redis is a purely key-value storage). To work with it, functionality was added in version 50.

In order to start using it you need

  1. ask the admin to install Redis
  2. ask him to install the redis module for PHP
  3. register in config.php
$config['redis_host'] = '127.0.0.1';
$config['redis_port'] = '6379';
$config['redis_database'] = 0; 
$config['redis_password'] = '';

if redis is hanging on a socket it will look something like this

$config['redis_host'] = '/tmp/redis.sock';
$config['redis_port'] = '0';

and that's all.

In this config, in addition to the clear fields, there are several new ones. redis_password - in most cases it is not relevant since now everything is on dedicated servers. redis_database - Redis does not have alphabetic database names, but rather numbers. If you have several sites, you can give each site its own number. But you don’t have to specify it and use one database for all sites. The difference will be that if you want to reset the entire cache and you use one database for all sites, the cache will be deleted for all sites. If each site has its own database, only that site’s cache will be cleared.

How is this better than memcached

  • It offers the same advantages over memcached as Couchbase.
  • Redis is a more cache-specific solution, but CouchBase has a ready-made convenient admin panel (talking about version 2+).

Where is cache stored? (memcache)

By default, a file cache is used (stored in /scj/cache), but you can also use, for example, Memcache. To do this, you just need to add it to scj/includes/config.php

$config['memcached_host'] = 'localhost';
$config['memcached_port'] = '11211';

The address and port may change (check with your admin), but in most cases they will be the same.

It makes sense to configure memcache to work via socket - it's faster. In this case, the config will be something like this

$config["memcached_host"] = "unix:///tmp/memcache.sock";
$config["memcached_port"] = 0;

There are several nuances:

  1. file cache is not as slow as it may seem. In practice, the difference is often smaller than people expect.
  2. with file cache, the cache stays on disk. If the server is overloaded or restarted, the cache does not simply disappear and the script does not have to rebuild everything from scratch. With memcache, the entire cache can be lost, and then the script must regenerate many pages on the fly, which creates extra load again. If you do use memcache, make sure it has enough memory. The exact amount depends on database size and on how heavy your templates are, since the cache stores the generated HTML itself. As soon as memory runs out, pages start being regenerated on the fly. Memcache size also matters because old entries are evicted when space is needed. For example, if the cache can hold 10 one-megabyte entries, adding an eleventh entry pushes the oldest one out. Another issue is fragmentation: memcache stores data in blocks, so real memory usage is higher than the reported payload size. Roughly speaking, if a block is 100 bytes and you save 1 byte, statistics may report 1 byte while 100 bytes are actually occupied. If an entry is evicted, memcache does not report an error back to the script, so the script cannot react to that directly. A rough practical estimate is about 15% fragmentation.

Why is thumb order different in the admin panel and on the site?

With the same sorting, the order should be the same, taking into account the following nuances:

1. The admin panel shows thumbs in database CTR order; for example, on the site page in some places there may be “new thumbs” that are being tested. For example, on the page thumb 123 is in 15th place, and in the admin panel it is in 50th place. This is probably a new thumb that the script is testing.

2. The new thumb may get an unexpectedly high CTR. For example, they showed it 2 times and clicked on it 1 time = CTR 0.5, but 2 impressions are not a reason to judge that the thumb is good. Therefore, by default, “new” thumbs are not shown in first place. You can change this in settings (New Rotation: New thumbs placement : Place new thumb (shows less then New thumbs timelive) on places other then Test positions start if it has good CTR. ). It’s easy to check if you select New Thumbs = dont show new in List Thumbs.

Why is there an empty tag cloud on my page

A tag cloud is generated from active tags every 30 minutes and stored in cache. Accordingly the options:

* no active tags

  • less than 30 minutes have passed
  • the cache was cleared

Thumbs (galleries) are not deleted

* previously there was a problem when deleting a large number of thumbs. For example, if one sponsor had 10k thumbs and you deleted that sponsor, the script tried to remove everything immediately and could hit a timeout. The issue was even worse if you needed to remove not just thumbs, but a full custom gallery.

  • now thumbs are deleted by cron. When you click “delete” in the admin panel, the thumb is not deleted instantly. It is moved to the 'Marked for deletion' status, and every 10 minutes cron checks for such items and removes them
  • if you need to delete “right now” - run rotation.php with the parameter process_deleted=true
  • cd /PATH_TO_/scj/bin/; env HTTP_HOST=yourdomain.com php rotation.php process_deleted=true 
  • the only exception: if you delete a thumb in Rotation - List thumbs and less than 30 thumbs are deleted, then the deletion occurs immediately.

The deletion speed is hard to predict and depends on the number of galleries involved, current server load, whether a custom gallery is involved, and whether the files are on the current server or on FTP.

How much traffic is needed to rotate thumbs

You do not need to finish testing every thumb to achieve good traffic productivity. However, you can easily estimate how much traffic a full test requires.

A thumb is considered rotated after it has been shown New thumbs timelive times, which is 500 by default. Let’s say there are 200 thumbs on the page, and the default percentage of test positions on the page is 15. That means new thumbs will be shown in 30 of those 200 positions. Every visit to the page means +30 impressions for new thumbs. For 10,000 thumbs at 500 impressions each, you need 5,000,000 impressions. With 30 test impressions per page view, this is 5,000,000 / 30, or about 167,000 page views.

Insufficient traffic is one cause. Another is that only one thumb per gallery may receive impressions initially. Suppose there are 100 galleries with 10 thumbs each and 20 positions per page. All CTR values start at zero. The first page displays the first thumb from galleries 1–20, and those thumbs receive clicks and impressions. On the next refresh, five positions are reserved for testing.

The 15 regular positions keep the first thumbs from galleries 1–15, while the five test positions can show the second thumbs from galleries 16–20.

If those second thumbs perform worse than the first thumbs from galleries 1–15, the next test can show the third thumbs from galleries 16–20.

Galleries 1–15 therefore still have impressions only on their first thumbs. They will leave the top positions when other galleries achieve higher CTR.

They also have the opportunity to be shown on page 2 of the pagination, but again, provided that your traffic reaches the 2nd page.

The &link=blabla parameter labels clicks for Stats - Links. Rotation uses the same parameter for its own tracking data, such as 12x123x1234. For example, a rewrite converts /gallery/cool-desc/index.html?12x345x567 into out.php?slug=cool-desc&link=12x345x567, and the script uses that data for thumb statistics. A trader link such as out.php?member=domain.com&link=top still works, but replacing a rotation link's tracking data with a label would break rotation tracking. Use &link2 for a separate label: out.php?slug=cool-desc&link=12x345x567&link2=blabla. This keeps both link statistics and thumb rotation.

What are category thumbs?

By default, a category thumb is the category’s best thumb by CTR. However, you can configure the script to use a thumb that is not the absolute best one, for example the 2nd or 3rd by CTR. These settings are available in Rotation - CMS - Settings.

How to create a master site from a slave

  1. Dump the master database.
  2. Find the departing slave’s ID (X) in rot_linked_db.
  3. Disconnect that slave from the master.
  4. Restore only rot_gallery_info, rot_gallery_statsX, rot_gallery_dataX and rot_thumbs from the dump into the former slave’s database.
  5. Rename rot_gallery_statsX to rot_gallery_stats1 and rot_gallery_dataX to rot_gallery_data1.

Pool, Active and Old are used by Shift settings in rotation groups. To publish galleries gradually, import them into Pool and configure a shift, such as 10 galleries per day. The script moves them to Active, making the site appear updated daily. Use Old when removing older galleries while keeping the active total constant.

On the site, the listing shows only galleries with the active status.

preload - galleries are added to Preload (in the admin panel) so that you can choose which of the grabbed thumbs will eventually be on the site. Those that you do not select will be deleted.

to_grab - when galleries are added to the database they receive this status before the grabber creates a thumb for them. At the moment thumbs are created, they receive the processing status. to regrab - gallery is waiting for regrab.

to delete - the gallery is queued for deletion. Large batches cannot always be deleted immediately.

grab error - if something went wrong while grabbing thumb, the gallery is either deleted or given the grab error status depending on your settings.

Banned - the URL remains in the database and will not be added again. Like grab error, this only makes sense if you are adding a gallery via import sets and there is a possibility that some galleries will be added again and again. For example, you add a set through import, gallery goes to preload. You selected part of the gallery, but decided not to add some. An hour later, this import set is added again, and there is the same gallery again - it will again end up in preload and you will have to sift it out again. To avoid that, you can add it to banned. The downside is that the database in this case grows and there is a gallery that is not used, but takes up space in the database.

Inactive (the equivalent of hidden in version 1.X) means the gallery is not shown in listings, but is still available by direct URL. For example, imagine a gallery was indexed but hotlinked its content from somewhere else. Later the source content was deleted and the gallery stopped working. Previously, the checker could delete such galleries, or mark them inactive. The downside was that for search engine crawlers the old URL would now return 404. In some cases it is better to return a page without content instead of a 404. That is what the “Hidden” status is for: the gallery remains accessible by direct URL, but its thumb is removed from rotation. This status can be assigned by an import set that removes galleries.

Gallery Checker has a similar option.

The exact effect on search engines is unknown.

Category statuses

Categories have 3 statuses:

  • active - the category appears in <category> lists, and its galleries appear in <thumb> lists.
  • not active - neither the category nor its galleries appear in those lists.
  • hidden - the category is not displayed in <category> lists, but its galleries still appear in <thumb> lists.

How to import a very large dump

Version 2.* can import large files through importset on its own, in practice handling very large files as long as they are reachable by URL. Just add the URL and the script will gradually import everything.

eval()'d code

If, when you access any page, you get something like “Parse error: some error, in /some/path/scj/tube/index.php(0) : eval()'d code on line 1717” - this 100% means that you have an error in your PHP code in the template.

In my experience, the most common problem is missing quotes. http://smartcj.com/wiki/doku.php?id=new_rotation_hints#php_code_in_template

Crop Profiles

These are sets of parameters for processing thumb.

If you only need the size on one side, but set the second side to 0. For example, if the width is specified and the height is 0, then the width will be fixed, and the height will change to fit the thumb size. This is true for sites like Pinterest.

Image Command is a command that is applied BEFORE the thumb is made. the only parameter {FILE} is the current image. For example,

/usr/bin/your_command -some_param {FILE}

Thumb Command - similar only for the already made thumb.

Face Detect - see FaceDetect

How to grab custom galleries

Sometimes you may not want to create another slave site, but instead want to grab a custom gallery from one of your other sites, for example when the original URLs are no longer available. If the gallery is built as a page with pictures on a separate page, the only way to grab it is Deep fetch. The problem is that such pages often contain links to tags, categories, and other pages with many additional thumbs, so Deep fetch tries to download all of them. If the custom gallery also uses skimming, the whole grab can become very slow.

It's better to do this:

  1. create a separate template, for example plain_gallery where all links will be directly to the picture, and not to a separate page
  2. and now you give these URLs to the grab in another script

How to copy rotation info

Rotation data is stored in rot_gallery_stats* tables, so if you need to copy rotation data from one slave to another you need

- see what ID the slave has from which we are copying

  1. what is the slave ID to which we copy
  2. copy(!) the table conditionally rot_gallery_stats2 to rot_gallery_stats3

Category tags do not work

The problem is usually in using a category tag on gallery pages, for example <!–CATEGORY_NAME–>, while the gallery may have more than one category and it is not clear which one should be displayed. Therefore, either a tag of the form <!–CATEGORY_1_NAME–> or the construction <groups … >…</groups> is used

Group Deactivation (Group Exclusion)

Let's say we have a master on which there are groups A and B. We connect a slave on which we deactivate group B. When sampling for a slave, we have 2 options:

* selection of all gallery EXCEPT group B

  • or all gallery from group A

at first glance they are the same thing. However, if our gallery is in both groups, then in one case it will be included in the selection, but in the other it will not.

So in settings there is a Group Exclusion setting

- Hard = the selection goes like “all the gallery EXCEPT group B” (those galleries that are in both groups are not included in the selection)

  1. Soft = the selection follows the second option, namely “all galleries from group A” (those galleries fall into the selection)

For example, suppose the master has straight, gay and teen groups, but a slave should show only straight content. Its visitors should not see gay content at all. Use Hard exclusion so a gallery assigned to an excluded group is omitted even if it also belongs to an enabled group.

Some page layouts cannot be grabbed automatically.

In this case, create a gateway script that converts the source into a format the grabber understands:

* for example, URL gallery http://gallery/, thumb http://gallery/image.jpg

Example:

Suppose we have a gallery at http://gallery/ with unusual markup:

<html>
<body>
<dont_grab_this src='http://gallery/0.jpg'></dont_grab_this>
<some_strange_tag src='http://gallery/1.jpg'></some_strange_tag>
<some_strange_tag src='http://gallery/2.jpg'></some_strange_tag>

The standard script parser cannot parse this, so we make the gate http://my_server/gate.php which parses this gallery and shows thumb from there (the code is simplified for the example, of course more checks are needed)

<?php

if (!isset($_GET['url']) or !$_GET['url']) die("Need url");

if ($html = file_get_contents($_GET['url']) ) {
	preg_match_all("|<some_strange_tag src='(.*?)'>|", $html, $out);

	$image_num = (isset($_GET['num'])) ? $_GET['num'] : 1;

	if ($out[1][$image_num-1]) {
		header("Content-type: image/jpeg");
		echo file_get_contents($out[1][$image_num-1]);
	}
}

check that the gate is working

http://my_server/gate.php?url=http://gallery/ http://my_server/gate.php?url=http://gallery/&num=2

At these URLs, the browser should display http://gallery/1.jpg and http://gallery/2.jpg from our gallery, respectively.

Now import this gallery, pattern: url|thumb_url

http://gallery/|http://my_server/gate.php?url=http://gallery/,http://my_server/gate.php?url=http://gallery/&num=2

As you can see here, the URL will be http://gallery/, and for thumb we will take the images that are visible at the URL http://my_server/gate.php?url=http://gallery/ and http://my_server/gate.php?url=http://gallery/&num=2.

Since we don’t know exactly how many pictures there will be in the gallery, we can add, for example, http://my_server/gate.php?url=http://gallery/&num=123 (that number is non-existent) to the thumb list - the script will simply not be able to grab it and will skip it.

Option 2: replacement at the import stage

Let's say we have import set http://sponsor/dump.php which produces a dump of the form

url|thumb_url|desc

and we decided to make a custom gallery from this content, but the problem again is that the gallery has the same appearance as in the previous example, but the grabber cannot grab it in normal mode.

Making a gate - option 2:

  • the gate receives the feed URL, grabs it, processes each line as a gallery and adds a field with pictures for a custom gallery, which in this case the gate produces a dump immediately in the form of url|thumb_url|desc|image_list
  • we add the set to the import immediately gate.php?url=http://sponsor/dump.php

Option 3: Import using XPath

For example, we have a new tube that gives a URL like http://tube/gallery.html; it doesn’t have an export; we grab flv_url and flv_thumb_url from there and make our own custom gallery from them.

* If you don’t know what xpath is, you should read it, self-education is useful

  • open your favorite browser - developer tools
  • open the page, find the desired element and do Copy - XPath
  • we get something like /html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2] , by now, if you read the first paragraph, you already understand that this is the path to the page element. This way the script will know where the element you need is located on the page. Of course, you don’t need the element itself, but its value, for example /html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2]/@href if it’s a link or @src if it’s an image, etc.
  • add url|flv_url|flv_thumb_url as a pattern, marking those fields in which you need to extract Xpath as XPath:/…. in our version it turns out something like
http://tube/gallery.html|XPath://html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2]/@href|XPath://html/head/meta[5]/@content

If you insert this line into the import, the Test Xpath button will appear. If you click on it, the script will pull out the gallery URL and calculate the specified fields. This is necessary to check that you have entered xpath correctly.

This way you can add as many URLs as you like

  
http://tubesite.com/gallery.html|XPath://html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2]/@href|XPath://html/head/meta[5]/@content
http://tubesite.com/gallery222.html|XPath://html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2]/@href|XPath://html/head/meta[5]/@content
http://tubesite.com/gallery333.html|XPath://html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2]/@href|XPath://html/head/meta[5]/@content

and thus the gallery will be added. But it's certainly not very pretty. Therefore, you can add Import Replacements where

url contains = tubesite.com
replace FLV Url = XPath://html/body/div[3]/section/div[1]/div/div[1]/div[2]/a[2]/@href

This way, you can simply import http://tubesite.com/gallery.html and the script will already replace the necessary fields for this site during import.

As usual, the best approach is to add one gallery first and check the grab log.

Option 4: ahhhh, everything is complicated, I don’t want to read and understand anything

If you don't want to do it yourself, you can always pay and have the work done for you. Any schoolchild can make a gate or copy xpath in a browser. If you don’t want to contact schoolchildren, contact the support with specific sites. Estimated price - $100 per site.

Lazy load, load on scroll, pinterest and so on

All these options are based on the fact that when scrolling to the end of the page, new content is loaded and the user does not have the page overloaded, but new content is added at the end of the page.

It looks like this: imagine an index template with 50 thumbs

<thumb num=1-50>
<a href='/...'><img src='<!--THUMB_URL-->'></a>
</thumb>

We add, for example, jquery.wookmark to the template (not the only option, of course) as in http://demo.smartcj.com/scroll/

upon reaching the end of the page it must load additional content, for this we indicate from where

var P_BASE = '/?force_template=index_scroll_ajax&page=';

As you can see, the index_scroll_ajax template is loaded and &page= is specified. Each time when the end of the page is reached, jquery.wookmark will load this URL changing the page number

Template index_scroll_ajax where we display 10 thumbs

<thumb num=1-10>
<a href='/...'><img src='<!--THUMB_URL-->'></a>
</thumb>

Duplicate test thumbs

The problem manifests itself on a database where thumb has not yet gained CTR\impressions at all: we open page 1, then page 2 (of the same sample) and we see repeated thumbs. The following happens:

For example, imagine we have 3 thumb positions per page, and only 9 thumbs total. That means there are 3 pages. test position -1 per page, 1 test 2 rotated thumbs. On page 1: we take 2 thumbs by CTR, since all CTR 0 get thumbs 1 and 2. We take the first test one - 3. It turns out 1 2 3.

Page 2 - we take the next 3 thumbs by CTR using the page offset, but since CTR values are still unstable, the sequence may become 4 5. Then we also need one test thumb, so the script again looks from the start, sees that thumb 1 still has no impressions and is still a valid test thumb, and produces 4 5 1. That is where the repetition comes from.

Once enough thumbs have CTR data to fill the regular positions, this source of repeated test thumbs disappears.

Fast Navigation

If you have a large database, then it makes sense to replace <pagination> with just <!–PREV_PAGE–> <!–NEXT_PAGE–>

The difference is that if we have navigation, we first need to calculate how many gallery there are for a specific request, this is a certain load on the database.

If we only have links to the next/previous pages, then there is no need to count anything in the database.

Please note that in this case the total_items tag will simply show the number of galleries on the current page.

User Thumbs

Suppose your import contains many thumbs, but there is not enough traffic to rotate all of them, which is the usual case. Still, you may want to keep all of them for rolling thumbs. That is what the User Thumbs option is for: the specified thumbs are downloaded, the crop profile is applied, but they are not added to the database. They are stored only on disk in /scj/thumbs/user_thumbs/.

Import these fields using the pattern URL|THUMB_URL|USER_THUMBS.

If it is not possible to provide two separate thumb fields in the import, you can simply import as URL|USER_THUMBS and set How Many Thumbs from each gallery ?= X. In that case, all thumbs from this field are saved to disk, while X thumbs are added to the database for rotation.

This way the database does not grow and there is no need to rotate extra thumbs.

At the same time, you need to understand that the script does not know anything about thumbs, which are stored in user_thumbs, so for rolling thumbs you have 2 options. Either for each gallery the number of thumbs should be the same, or when rolling, the script should preload thumb for rolling and thus understand how many there are in total.

In the template, the URL to the directory with the user thumb for this gallery can be obtained with the tag

<!--USER_THUMBS_FOLDER-->

Filter request parameters

For example, you have a website in English and there is a search form where people enter search queries on the site. A log of search queries is displayed somewhere on the site. Some people try to search, for example, in Russian and this is displayed in the query logs, but you would not want this to be visible. You can filter unwanted characters at the request stage.

Add to common.php

if (isset($_GET['search'])) $_GET['search'] = preg_replace('|[^a-z,0-9,\s]|is','',$_GET['search']);

and these will only be Latin characters

There is also an option “Log empty search queries” and if nothing is found according to the request, it will not be logged.

After the update, an option was added to the rotation settings that does the same thing

Search query filter pattern (regexp)
we use php preg-replace function to replace non-valid characters in user input
ie when a surfer searches on your site
a good pattern to start is
/[^\p{L}\p{N}\s]/u 

Multiniche trade

Let's look at what is in the script for maintaining multi-niche sites with a new rotation, except for the direct presence of categories.

Incoming redirect to a niche page - the script can redirect traffic from a trader to the desired niche on your website (redirects).

Sending a click to a trader’s niche page - if a trader cannot automatically redirect your hits to the desired page, you can set up such a redirect yourself, although this is somewhat more complicated than simply enabling the option. First, you need to ensure that when you click, the script understands which group it is dealing with, so add &group=… to the output. There are 2 options:

  1. edit the template and make links like /gallery/asd/index.html?12x12x1234&group=GROUP NAME (substituting the corresponding tag in each template)
  2. or enable the option (trade_by_groups) and determine the group by referrer. Then, in each trader’s settings, you can set Special Urls for each group. So if group A has the URL http://trader/a/ and the out parameters determine that the current group is A, the trader will be sent to http://trader/a/ instead of the generic http://trader/

Note what they forget when analyzing these functions

Trader 1 is in group A, but I see in the referrals of trader 1 referrals from my site from category B - he does not trade in groups! Usually the toplist is built globally, not by group, and then included on all pages of the site. That means page B will still show the top of all traders, even traders that should only appear in group A. Toplist

In addition, if there are, for example, 2 traders in group A, the surfer has visited both, then when clicked it will be sent to all traders. If there are no active traders in the group and the surfer has not been there, he sends them to everyone.

Performance

Rotation requires a large number of pages.

Here is the usual situation: you have a 200k gallery in 300 categories, let there be an average of 7 pages per category, 3 sorting options (ctr, data, duration) = 6300 possible pages + 200,000 gallery pages themselves.

Generating that many pages as static files via cron would make little sense, so the pages are generated dynamically and cached instead. You control the cache time in the config. The shorter the cache time, the more pages the script must regenerate every second, so you directly affect server load.

A new site needs to warm its cache. If you immediately send 5,000 visitors across many pages, the script must generate all those pages at once. Increase traffic gradually to avoid overloading the server. For example, start with 1,000–2,000 visits in the first hour to cache the main pages, then increase traffic.

How much traffic the server can handle: after the cache is created, cached pages can be served almost immediately. It looks like this: 1 person came to the new site for the index, we created an index page and put it in cache for the time specified by you in the config. All other visitors will receive this page from the cache with virtually no load on the server. Even if 1M users come to this page during the cache time, they will receive the page without any problems.

If we have just 1 website, let’s say 50k or 500k traffic - it doesn’t matter, because anyway we need to create almost the same number of pages for both 50k and 500k.

But if you have 50 sites with 10k traffic each, in terms of load this is not the same as 1 site with 500k, because for 50 sites you need to create 50 times more pages than for one (with the same database size, number of categories, etc.).

The size of the database also directly affects the load: if you have 100k in the database, then depending on the design it will be the same 3000 pages, 200k - 6000 pages.

Translations and slave sites are technically similar to adding one more site, because a translated version or a slave with different descriptions or design still needs its own page generation. The difference from a completely separate second site is that some data is shared. So two fully different sites with 100k galleries each are not the same as a master with 100k galleries plus a slave, because in the master/slave case some information overlaps and the database can reuse part of it, which means less load.

Server capacity cannot be predicted from hardware alone: the number of sites, design and database size all matter. Measure it with your actual workload. The script is continually optimized for speed.

Overload can escalate quickly. A server may not merely become a little slower at full capacity: requests can accumulate until it stops responding. Think of an engine pushed beyond its limit: it can seize rather than simply lose power. Monitor the server as traffic grows.

Performance Log

Templates often include a lot of their own PHP code, and at some point it becomes not entirely clear what exactly loads the server more: the script or its own code. To roughly look at this in the rotation settings there is

Performance Log Writes performance info into logs/perfomance.log Adds some load at HDD as it writes each hit.

When turned on, it writes to logs/perfomance.log, which creates a small additional load, so you shouldn’t leave it turned on unnecessarily. However, you can turn it on for a while to check the current state.

The main advantage is that later in Maintenance -Logs you can look at this log and the script will automatically group the indicators so that you can see general statistics, and not just a lot of text. The names of the fields there change as this log is added, but in 99% of cases it is not a problem to understand what each entry means. If something is not clear, you can always ask on the forum.

Custom gallery URL Refresh

A gallery URL such as http://domain/gallery/asd.html is rewritten to out.php?url=content&slug=asd. Skimming comes from the default settings or the rewrite rule, so refreshing the gallery can send the visitor to a trader.

It is impossible to avoid this automatically because a refresh is when the browser sends exactly the same request and there is no way to distinguish it on the script side.

In general, I don’t consider this a problem because only the webmaster himself refreshes the gallery during the design process, but if you want to avoid this, you can add code to the page that will be executed when refresh is pressed

https://stackoverflow.com/questions/18457797/how-to-know-whether-refresh-button-or-browser-back-button-is-clicked-in-firefox

instead of alert(“refresh button is clicked”); you can put your own code that will redirect for example to http://domain/gallery_PERMANENT/asd.html , and in rewrite add gallery_PERMANENT which will make a URL with &p=100

Site Internationalisation (i18n)

Translation of the site into other languages.

It’s quite easy to translate the site menu (those links like Most Popular, Order By date, etc.) into other languages. For example, we have the phrase “Most popular”. And several languages ​​for which this phrase needs to be translated.

In Rotation - CMS - TPL Custom Vars, create a variable named most_popular. Use <!–CUSTOM_VAR_MOST_POPULAR–> in templates; the variable editor shows the corresponding tag. You can also enter translations for language slaves there.

Case Sensitive URLs

URLs can be case-sensitive, so http://domain/aaa and http://domain/AAA may identify different pages. The database URL field is case-insensitive by default to make searches predictable when URLs were imported with inconsistent capitalization.

However, it happens that the URLs are really different and the database needs to distinguish the case. To do this, you need to run in the database

ALTER TABLE `rot_gallery_info` CHANGE `url` `url` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL; 
ALTER TABLE `rot_gallery_info` CHANGE `source_url` `source_url` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL; 

and remember that after this the URLs from the example above will become different and when searching for URLs you will need to look at the case of letters.

How to move thumbs

By default, thumbs are saved in /scj/thumbs. If you want to change the thumb storage location after adding content, then you need to

- Move the thumbs from scj/thumbs to the new location.

  1. change URL to thumbs in CJ settings - grabber settings

Full page cache

For highly loaded sites, page cache in its already completed form helps significantly. For example, we have a template

<thumb num=1-2>
<!--THUMB_URL--> 
</thumb>

<?php
echo "date: " . date("Y-m-d");
?>

The script parses the template and replaces it with data from the database and stores the result in cache, so that the next surfer who looks at the same page will no longer have to replace the script tags

/thumbs/img1.jpg
/thumbs/img2.jpg

<?php
echo "date: " . date("Y-m-d");
?>

The PHP code remains in its original form in this cache and executes separately for each visitor.

Executing that PHP usually adds little load. On busy sites, full-page caching can save additional work by caching the output of PHP as well. For example:

/thumbs/img1.jpg
/thumbs/img2.jpg

date: 2023-01-01

In most cases, this is ok, because the result of executing the code is the same for all surfers.

Enable full-page caching with the following setting. If some PHP must run for each visitor, such as code using the current IP address, mark it as dynamic as shown below.

$config['full_page_cache'] = true;

In this case, you can use the tag in the template

<php_code no_cache=true>
<?php
echo "user IP: " . $_SERVER['REMOTE_ADDR'];
?>
</php_code>   

and it is this code that will not be cached.

For example template

<thumb num=1-2>
<!--THUMB_URL--> 
</thumb>

<?php
echo "Rand: " . rand(0, 100);
?>

<php_code no_cache=true>
<?php
echo "user IP: " . $_SERVER['REMOTE_ADDR'];
?>
</php_code>   

will be cached as

/thumbs/img1.jpg
/thumbs/img2.jpg

Rand: 22 (here you should pay attention that this PHP code is cached in its completed form)

<?php
echo "user IP: " . $_SERVER['REMOTE_ADDR'];   

// and here is the PHP code in its original form and will be executed for each surfer

?>

Something to pay attention to when changing the template for full_page_cache. For example, your code is

<?php
$img_src_hash = md5($_SERVER['REMOTE_ADDR']);
?>

<img_src='get_img.php?hash=<?=$img_src_hash?>'

some more HTML

We cannot cache it completely because this code must be different for each surfer. Whatever hash or cache you want to do

<php_code no_cache=true>
<?php
$img_src_hash = md5($_SERVER['REMOTE_ADDR']);
?>
</php_code>   


<img_src='get_img.php?hash=<?=$img_src_hash?>'

some more HTML

however, you need to remember that get_img.php?hash=<?=$img_src_hash?> will be stored in cache already executed, for example as get_img.php?hash=322jjJ!…., so any part that must output runtime data must also be treated as dynamic.

<php_code no_cache=true>
<?php
$img_src_hash = md5($_SERVER['REMOTE_ADDR']);
?>

<img_src='get_img.php?hash=<?=$img_src_hash?>'

</php_code>   


some more HTML

Probable errors

You cannot include <php_code no_cache=true> in another block <php_code no_cache=true>. For example,

<php_code no_cache=true>
<?php
$img_src_hash = md5($_SERVER['REMOTE_ADDR']);
?>

some HTML

<php_code no_cache=true>

Another code

</php_code>   

more HTML


</php_code>   


some more HTML

In this case it's obvious, but there might be an option

<php_code no_cache=true>
<?php
$img_src_hash = md5($_SERVER['REMOTE_ADDR']);
?>

</php_code>   


<!--INCLUDE_TEMPLATE... 

some more HTML

in the template you include there is also <php_code no_cache=true>

GET variables pass-through

For example, you received a hit with the parameter

http://your_domain/?param=123

To include this value in the page output, for example:

<img src='https://your_tracker/?param=123'>

all you need to do is in the template

  <img src='https://your_tracker/?param=<!--GET_param-->'>
  

GET_param - will be replaced with the current value

Reset Models

If you already have a gallery database, let's say the gallery descriptions contain model names. The models themselves are simply added to Rotation - Models.

The task is to assign gallery models (Rotation - special - Reset models)

The search for a model name is done through the built-in search, the settings of which are located in Rotation - Settings.

There are 3 options

1. Plain MySQL searches for the model name with spaces around it, such as “ Ola ”, so a short name is not matched inside another word such as “ebola”. The default search is not case-sensitive.

2. MySQL fulltext supports case-sensitive matching.

3. Sphinx supports case-sensitive matching and different word endings.

Therefore, if you need better model assignment + better search in general, you must at least enable mysql fulltext

new_rotation_faq.txt · Last modified: by user